欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

Http Only Cookie保护AccessToken

发布时间:2023/12/4 编程问答 48 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Http Only Cookie保护AccessToken 小编觉得挺不错的,现在分享给大家,帮大家做个参考.
【导读】JWT认证方式目前已被广泛使用,一直以来我们将token放在请求头中的Authorization中,若通过此种方式,一旦token被恶意窃取,攻击者可肆意对用户可访问资源进行任意索取

我们大多都是通过登录成功后,响应AccessToken,然后由前端将token存储在相关Storage中,然后每次将其放请求头而认证请求,由于token是极其敏感信息,所以我们不能将其交由前端去处理,而应由后台获取对前端不可见

对安全有较高要求的平台,我们通过Http Only Cookie来解决token恶意窃取问题

Http Only Cookie

Http Only Cookie简言之则是将相关信息响应时存储在Cookie中,而客户端脚本无法访问,每次请求时,则将自动携带所有信息到服务器。例如,京东存储相关信息

接下来我们看看在.NET Core中如何将AccessToken以Http Only方式存储在Cookie中

[AllowAnonymous] [HttpGet("api/test/get")] public IActionResult Get() {Response.Cookies.Append("x-access-token", GenerateToken(),new CookieOptions(){Path = "/",HttpOnly = true});return Ok(); }

如上,我们模拟登录成功,并不返回AccessToken,而是将其写入到响应头中,上述Cookie选项HttpOnly为true即表示客户端脚本不可访问

此时我们来访问如下需认证接口

[HttpGet("api/test/say")] public string Say() {return "Hello World"; }

用过JWT的童鞋都知道,标准模式则是将AccessToken写入到Authorization中,即请求头【Authorization: Bearer ......】,那么上述是如何认证成功而请求到接口的呢?

当我们添加JWT认证时,每次请求在其对应事件OnMessageReceived中将自动获取请求头Authorization中的值,将其赋值给context.Token

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => {......options.Events = new JwtBearerEvents{OnMessageReceived = context =>{//Bearer Tokencontext.Token = "";  return Task.CompletedTask;}}; });

你问我是怎么知道的,我是猜的吗,当然不是,丢出官方源码就知道了,直接找到JWT如何处理认证则一目了然

protected override async Task<AuthenticateResult> HandleAuthenticateAsync() {string token = null;// Give application opportunity to find from a different location, adjust, or reject tokenvar messageReceivedContext = new MessageReceivedContext(Context, Scheme, Options);// event can set the tokenawait Events.MessageReceived(messageReceivedContext);if (messageReceivedContext.Result != null){return messageReceivedContext.Result;}// If application retrieved token from somewhere else, use that.token = messageReceivedContext.Token;if (string.IsNullOrEmpty(token)){string authorization = Request.Headers[HeaderNames.Authorization];// If no authorization header found, nothing to process furtherif (string.IsNullOrEmpty(authorization)){return AuthenticateResult.NoResult();}}.......  }

到这里我们知道了自动获取Token的原理,我们修改了Token存储方式,照葫芦画瓢就好,如此将覆盖默认标准模式,如下:

OnMessageReceived = context => {var accessToken = context.Request.Cookies["x-access-token"];if (!string.IsNullOrEmpty(accessToken)){context.Token = accessToken;}return Task.CompletedTask; }

从分析自动获取Token原理,我们也可知道,若与第三方对接,依然可以使用请求头Authorization标准模式认证,因为Cookie为空,再次获取Authorization值

注意:发现若将前端未置于wwwroot下,即完全前后分离,涉及到跨域的情况下,比如使用的是axios封装请求,那么应该必须在请求头中添加【withCredentials:true 】,否则使用Http Only将无效,出现401

额外意外发现一个很有意思的问题,未深入研究,这里当做小知识了解下就好,或许是我自以为发现新大陆了呢

当我们创建AccessToken时,都会设置一个过期时间,我们知道此过期时间肯定不会设置过长,但是若在比如移动端微信小程序中,若设置时间不长,必然要考虑刷新Token问题,为了懒一点,我们将Token设置为永不过期,那么JWT支持吗?

当然支持,只不过根据我刚好尝试了几次,找到了JWT永不过期的上限,最大只能是16年,若超过此临界点,比如17年,如下:

将会出现401,具体错误如下:

了解,了解就好,也没啥鸟用,我也是经常会瞎想,比如考虑某些可能存在的极限情况

总结

以上是生活随笔为你收集整理的Http Only Cookie保护AccessToken的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。