最近自己的小项目使用前后端分离的模式,用户认证使用jwt进行操作。网上搜集了一番,也看了不少spring security+jwt的demo项目。发现大部分都是在用户登录后把token存储到redis中的。于是我在开发使用中,也遇到了一些问题,产生了些许思考。
首先说说网上的jwt+redis的认证模式逻辑。
当用户登录成功时,会利用jwt把用户、权限信息生成token,然后把用户id当key,token当value存到redis中,存完再在响应头中设置token返回给前端。
前端收到后会存到localStorage中,也有存到sessionStorage中的,存到sessionStorage中肯定不行,关闭浏览器,下次再打开就没了,难道再登陆一次吗?可上次的token还没失效呢,这不是浪费资源吗。
前端把收到的token存起来主要是为了一些页面用来判断用户的登录状态,然后根据是否登录显示不同信息。
我不知道前端有没有更好的判断是否登录的方法,总感觉这种不太好,而且前端很容易伪造信息欺骗登录状态。不过伪造也只是静态页的展示,后台需要登录才能展示的数据一样获取不到,后端可不是纸老虎做的,那么轻易的被伪造的登录信息欺骗。这是一点前端的疑惑。
后端关于token的存储也有些疑惑,这个疑惑体现在多浏览器(设备)登录、登出的时候。
首先当用户在一个浏览器登录后,再在另一个浏览器登录的时候肯定会更新服务端redis中存储的token,因为key都一样嘛(都是用户的id),这样的话,第一个浏览器登录的token就会失效。
不过这也实现了只允许一个浏览器(设备)同时在线😂。但是我要想实现同时可以多浏览器(设备)在线呢,这种方案肯定就不行了。
不过在这个基础上我也想到了另一种实现方式,就是用户在一设备登录过,其他设备登录时,成功验证用户名密码后,判断redis中是否有该用户的token信息,有的话直接返回前端使用,多个设备使用同一个token。当用户退出时,只清除当前设备前端存储的token信息。否则连服务器的token一块清除的话,所有设备token都会失效。还有登录时记录当前用户登录的设备数,当为1时,退出登录则删除服务器token信息。
不知道关于jwt的用户认证体系是不是这样用的,虽然能够满足需求,但是总感觉这不是最正规的打开方式,不够优美。希望日后的实战中能够摸清他的真面目