token需要放在redis吗?

新人学习token鉴权有个疑惑,token本身有加密的用户信息,并保存在客户端.如果token只存在客户端,感觉并不够安全,且无法主动退出登录(无法主动过期).

听说一般token都存在redis里,那本质上就是在服务端也保存了token,可以通过token-userId的形式存储.如果是这样的话,token本身的意义是什么,token根据就不需要携带用户信息

似乎可以在客户端创建一个随机clientId,然后携带在header上,调用登录接口后, 后端以clientId-userId的形式将clientId存在redis里.这种方式似乎更简洁, 携带的数据量更少也更安全

阅读 3.6k
6 个回答

梳理下你的问题:

  1. token是否只需要存在客户端。
    token需要存储在服务器端。客户端存token是因为服务器端要鉴权,所以获取到token后要存下来。如果服务器端校验这个token已经失效,客户端需要跳转到登录页面。客户端可以通过退出登录失效token。
    完整流程:用户登录 - 登录成功 - 服务器颁发token - 用户带着token使用系统 - token失效/用户退出登录 - 整个流程再来一遍
  2. token的意义是什么。
    token用来判断用户的登录态,token必须跟用户绑定。
  3. 是否客户端颁发类似token的东西
    这个token必须是服务器端颁发的,并且只能是在用户名密码校验成功以后颁发。客户端给自己颁发岂不是监守自盗了。

因为一旦token生成后,就无法修改信息,但是实际业务有个场景比如说token过期时间是30天,该用户因为某些操作遭到封禁,我现在需要踢出用户,但是token已经下发了没办法收回与修改,这时候token存在redis就有用了,正常权限验证除了解析token是否合法,还得判断token是否在redis里,至于redis里面存个userId也好,存个数值1也好,只要有这个key就行了,你要是想踢出这用户,删除这个key就行

不一定要放在redis里面,只不过这种方式现在用的人多,比较普及。

最简单的情况,你可以把token数据放在程序内存里面,但是有问题,一个是内存占用的问题,二是程序有多个实例的情况下不方便共享数据,三是不能持久化数据重启后会丢数据。

也可以把token直接放在数据库里,用户基数比较多的情况下,每个请求都查询一次数据库,数据库压力还是有点大的。

所以现在比较流行把token放在redis里面缓存一下,查询效率会比较高,上面几个问题都能一次解决。


token本身可以不用携带用户信息,使用一个随机Key就可以作为token发送给客户端,客户端后面的请求,服务端只要在后台记录这个token和用户的绑定关系,就能获取到用户的信息,就能达到鉴权的目的。生成随机token的时候,降低重复的概率,在token里面加个userid等信息也是可以的。

1、token本身可以带用户信息也可以不带啊,服务端发放token的时候无非就是返回一个字符串,里面要包含什么内容是服务端定义好的,但是一般必须的有超时时间和其他可以公开的信息,比如jwt本身就是明文的,要么你就放可以公开的信息,要么就放加密过的信息
2、token在发放的时候需要对请求token的用户进行身份校验,然后客户端带着token去请求服务端的其他资源,起到的就是一个鉴权的作用,但是要不要在收到客户端的token时再次根据token里的用户信息进行校验(因为可能token里根本没有用户信息)这是不一定的,服务端完全可以只看token对不对得上而不必管是哪个用户发起的就放行资源
3、放Redis纯粹只是出于减轻服务器压力,减少响应时间考虑而已,放哪里其实都可以
4、token是肯定要放在服务端的,要不然没法鉴权

大家都答的很好,题主说的这个就是session的设计思路,服务器在登录鉴权完成后,生成session的k-v, k是session_id, v就是要存用户的信息比如uid, 然后把session_id返给客户端,下次客户端在cookie里带上session_id就变成的有状态的请求。
你看,即使在早期也是服务器生成kv, 因为对后端来说,前端都是可能伪造,是不可信任的。尤其bs架构,前端兼职就是在裸奔。我完成可以用和你一样的生成逻辑,比如你的token是基于一段md5对uid的加密,一般id是递增的,那我就可以用伪造的token非法访问资源。

使用jwt做token的话,服务端其实可以不保存token,主动退出登录之类的逻辑可以通过在jwt内容中添加标记字段来实现

推荐问题
宣传栏