关于JWT一点自己的理解

开篇

jwt是 json web token的简称,V2上看到一篇帖子 https://www.v2ex.com/t/590337?p=2 看完颇感慨,感觉每个人对JWT都有自己的理解和应用。而我更是JWT的重度用户,基本上小程序、app、网站全部都在用JWT。

JWT 是什么

我觉得JWT就是一段数据,进行加密签名,返回给客户端,我们称之为token。 客户端每次请求API时,header里带上token,由服务端再验证token的合法性。这个过程,其实配合filter 或 middleware 也可以实现自己的JWT。当然为了与其他系统兼容,我们还是用这套标准。

JWT 解析

jwt生成的token,看似一段乱码,其实它由三部分组成,{ token类型 + data + 签名} ,并且其中data可以解析出来。所以这里不建议放敏感数据,如信用卡号、password啥的,我一般会放两个关键数据 guid + exp,即用户guid 和过期日期。这样就不会像V2这篇帖子里的同学一样,每次还带上userid参数。过期日期只是用作续token用,比如服务端设置的是两个月过期,那么客户端可以在最后10天再请求一次,那么新的token又可以用两个月。

JWT 有效期

jwt可以设置有效期

var token = new JwtSecurityToken(
                "https://136cc.com",
                "moz_application",
                claims,
                expires: DateTime.Now.AddDays(1), //这里设置有效期
                signingCredentials: credentials);

JWT 如何log out

有效期内的JWT是主动吊销不了的,服务端只管JWT签名的合法性,合法就进去,不合法就返回401。那怎么办呢,目前看到有两个办法。

  1. 存储token到mysql或redis,再建立黑名单比较机制。
  2. 每一个用户存不同的签名key,这样如果想吊销某人的token,改一下他的key既可。
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("key")); //不同用户不同key
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha512);

            var token = new JwtSecurityToken(
                "https://136cc.com",
                "moz_application",
                claims,
                expires: DateTime.Now.AddDays(1), //设置token有效期
                signingCredentials: credentials);

这两种办法我都没试过,我想理论上是可行的。 当然常见一般客户端logout,也是清空token,然后alert('成功退出') [笑脸]

如何防止jwt token被盗

如果别人拿到token,可能就真的没办法了,就跟cookie被盗用一样的问题,你能怎么办。所以这里就只有想办法如何好好保护token了,比如app端可以用keyChain方案等。如果用在web上,还是建议存为cookie , 并将 HttpOnly 设为 true 。

web上如何使用 jwt

一般JWT用于app、单页应用,很少用于传统web,但利用.net core的中间件机制,也是很方便用于web的,对于网页端和服务端都是无感的。 这里分两个步骤。
第一步 将获取到的token放入cookie。
第二步 新建中间件,在中间件里将cookie再存入header

var cookie = "获取到的cookie";
context.Request?.Headers?.Append("Authorization", "Bearer " + cookie);