如何解决在重定向到其他URL时也存储对Cookie的声明,并且无需身份验证
如果这是可行的,我只需要提出建议。我正在为Shopify应用程序开发授权,我需要某种程度上存储来自shopify auth的访问令牌,以便将来对前端应用程序进行验证。
[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始终为空。
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 举报,一经查实,本站将立刻删除。