微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在重定向到其他URL时也存储对Cookie的声明,并且无需身份验证

如何解决在重定向到其他URL时也存储对Cookie的声明,并且无需身份验证

如果这是可行的,我只需要提出建议。我正在为Shopify应用程序开发授权,我需要某种程度上存储来自shopify auth的访问令牌,以便将来对前端应用程序进行验证。

所以shopify调用的第一个端点就是这个端点:

    [HttpGet("install")]
    public async Task<IActionResult> Install()
    {
        try
        {
            if (ModelState.IsValid)
            {
                var queryString = Request.QueryString.Value;
                var isValid = _shopifyService.VerifyRequest(queryString);

                if (isValid)
                {
                    var shopifyUrl = Request.Query["shop"];
                    var authUrl = _shopifyService.BuildAuthUrl(shopifyUrl,$"{Request.Scheme}://{Request.Host.Value}/api/shopify/authorize",Program.Settings.Shopify.AuthorizationScope);

                    return Redirect(authUrl);
                }
            }
        }
        catch (Exception ex)
        {
            var exceptionMessage = await ApiHelpers.GetErrors(ex,_localizer).ConfigureAwait(false);
            ModelState.AddModelError(new ValidationResult(exceptionMessage));
        }

        ModelState.AddModelError(new ValidationResult(_localizer["InvalidAuthStore"]));
        return BadRequest(ModelState.GetErrors());
    }

这很好用,此api调用的结果实际上将重定向到与我的api相同的链接,但这将授权该应用程序:

    [HttpGet("authorize")]
    public async Task<IActionResult> AuthorizeStore()
    {
        try
        {
            if (ModelState.IsValid)
            {
                var code = Request.Query["code"];
                var shopifyUrl = Request.Query["shop"];

                var accesstoken = await _shopifyService.AuthorizeStore(code,shopifyUrl).ConfigureAwait(false);

                var identity = User.Identity as ClaimsIdentity;
                identity.AddClaim(new Claim(Constants.Claims.Accesstoken,accesstoken));

                // genereate the new ClaimsPrincipal
                var claimsPrincipal = new ClaimsPrincipal(identity);

                // store the original tokens in the AuthenticationProperties
                var props = new AuthenticationProperties {
                    AllowRefresh = true,ExpiresUtc = DateTimeOffset.UtcNow.AddDays(1),IsPersistent = false,IssuedUtc = DateTimeOffset.UtcNow,};

                // sign in using the built-in Authentication Manager and ClaimsPrincipal
                // this will create a cookie as defined in CookieAuthentication middleware
                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,claimsPrincipal,props).ConfigureAwait(false);


                Uri uri = new Uri($"{Program.Settings.Shopify.RedirectUrl}?token={accesstoken}");
                return Redirect(uri.ToString());
            }
        }
        catch (Exception ex)
        {
            var exceptionMessage = await ApiHelpers.GetErrors(ex,_localizer).ConfigureAwait(false);
            ModelState.AddModelError(new ValidationResult(exceptionMessage));
        }

        ModelState.AddModelError(new ValidationResult(_localizer["InvalidAuthStore"]));
        return BadRequest(ModelState.GetErrors());
    }

因此上述api将在shopify中授权我的应用,并返回访问令牌。我要使用cookie身份验证类型将accesstoken保存在声明身份中(这是未经授权的用户凭据)。此时仍然没有错误,并且在调用HttpContext.SignInAsync函数之后,我仍然可以使用调试器查看新添加的声明。

您可以在代码中看到,在分配声明后,我调用将应用重定向到前端链接(注意:前端和后端具有不同的网址)

在我的前端应用程序中,我有一个Nuxt中间件,我放置了逻辑来检查从后端接收到的令牌,因为我仅使用查询参数将令牌传递给前端应用程序。这是我的中间件代码

export default function ({ app,route,next,store,error,req }) {
  if (process.browser) {
    const shopifyAccesstoken = store.get('cache/shopifyAccesstoken',null)

    if (!shopifyAccesstoken && route.query.token) {
      // if has token on query params but not yet in cache,store token and redirect
      store.set('cache/shopifyAccesstoken',route.query.token)
      app.router.push({
        path: '/',query: {}
      })

      // verify access token on the route
      app.$axios
        .get(`/shopify/verifyaccess/${route.query.token}`)
        .catch((err) => {
          error(err)
        })
    } else if (!shopifyAccesstoken && !route.query.token) {
      // if does not have both,throw error
      error({
        statusCode: 401,message: 'Unauthorized access to this app'
      })
    }
  } else {
    next()
  }
}

在我的中间件中,当路由的查询参数等于token=时,它将调用一个api来验证保存在我的声明身份中的accesstoken:

    [HttpGet("verifyaccess/{accesstoken}")]
    public async Task<IActionResult> VerifyAccess(string accesstoken)
    {
        try
        {
            if (ModelState.IsValid)
            {
                var principal = HttpContext.User;
                if (principal?.Claims == null)
                    return Unauthorized(_localizer["NotAuthenticated"]);

                var accesstokenClaim = principal.FindFirstValue(Constants.Claims.Accesstoken);

                if (accesstoken == accesstokenClaim)
                {
                    return Ok();
                } 
                else
                {
                    return Unauthorized(_localizer["NotAuthenticated"]);
                }
            }
        }
        catch (Exception ex)
        {
            var exceptionMessage = await ApiHelpers.GetErrors(ex,_localizer).ConfigureAwait(false);
            ModelState.AddModelError(new ValidationResult(exceptionMessage));
        }

        ModelState.AddModelError(new ValidationResult(_localizer["InvalidAuthStore"]));
        return BadRequest(ModelState.GetErrors());
    }

查看上面的代码,总是使我失败,因为我在authorize端点上保存的声明身份不存在,或者总之,ClaimsIdentity始终为空。

这是我注册Cookie配置的方法

    private void ConfigureAuthCookie(IServiceCollection services)
    {
        services.AddAuthentication(option =>
        {
            option.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            option.RequireAuthenticatedSignIn = false;
        })
        .AddCookie(options => {
            options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
            options.SlidingExpiration = true;
            options.Cookie.Name = "shopifytoken";
        });

        services.Configure<CookiePolicyOptions>(options =>
        {
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });
    }

,并且我还将app.UseAuthentication()app.UseAuthorization()放在Startup.Configure

请让我知道这是否令人困惑,因此我可以对其进行修改。我的主要目的是能够访问我在ClaimsIdentity中保存的accesstoken,以便我可以验证令牌。之所以要这样做,是因为当前的shopify还没有用于验证访问令牌的API。因此,当用户访问http://example.com/?token=<any incorrect token>这样的我的应用程序链接时,他们就可以访问我的应用程序。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。