首页
学习
活动
专区
工具
TVP
发布

Session与JWT

前言

Hello World!怕是大多数程序员写的第一句代码了吧。我就是用C语言写的第一个代码就是它了。虽然现在没有从事有关C语言的工作,不过还是受益于学习它所经历的每一行代码。

登录注册怕是写web应用里的Hello World!级存在了。第一份工作做的是j2ee和app,做的第一个模块就算是它了。不过这个”Hello World!”可一点都不简单。

正文

首先我们先搞清楚什么是认证和授权。百度一下发现很掉书袋。其实吧简单来说就是:认证就是让服务器知道你是谁,授权就是服务器让你知道你什么能干,什么不能干

认证授权俩种方式:Session-Cookie与JWT

Session

服务器只有一台,客户端却有千千万。怎么能够让服务器知道当前请求服务的是哪台客户端呢?我们举个生活中的例子:

你去图书馆(服务端)借书(请求服务)。先得办卡(登录获取session_id)吧,放兜里(cookie)。去刷卡处刷卡看看卡是不是伪造的,看看卡里的信息和数据库比对下看看有没有过期等等(检查session_id是否被篡改,是否失效根据session_id查询下内存或者数据库(通常是内存数据库)里对应的有没有过期)。过期不给进重新办卡(重新登录认证),没过期就给进(返回你请求的结果)

所以咯流程就是这样子:

当 client通过用户名密码请求server并通过身份认证后,server就会生成身份认证相关的 session 数据,并且保存在内存或者内存数据库。并将对应的 sesssion_id返回给client,client会把保存session_id(可以加密签名下防止篡改)在cookie。此后client的所有请求都会附带该session_id(毕竟默认会把cookie传给server),以确定server是否存在对应的session数据以及检验登录状态,权限啦巴拉巴拉……如果通过校验就该干嘛干嘛,否则重新登录咯。

前端退出的话就清cookie。后端强制前端重新认证的话就清或者修改session。

JWT

这里就不介绍jwt的三部分组成、由什么组成、怎么生成加密了。

日常的举个生活中的例子吧:

你去游乐园(服务端)玩耍(请求服务)。先得买门票(登录获取token)吧,放兜里(cookie、header……)。去检票口检票看看票有没有过期(检查token是否失效)。过期不给进重新买票(重新登录认证),没过期就给进(返回你请求的结果)

有没有觉得和Session有什么不一样?server不用存储信息了。一切都存在客户端。个人觉得这就是最大的不同。

这里大致列下俩者区别,一些比如JWT更简单、APP对支持不易的一些已经解决或者细究觉得很扯的或者大同小异的不在此列

SessionJWT

安全性

首先这个还真不算什么。现在WEB框架该都内置了防CSRF。而且既然知道有这个编写代码注意下也是应该的。

存储

这个还真是,JWT真心可以,不过得看情况。如果考虑可控性,那你简直想哭。

可控性

服务端存储认证相关信息还是很有必要的。举个栗子。如果你发现你账号被异地登录,你肯定想着换密码呀。换了以后发现我去,怎么又被异地登录。因为Token未过期,人家还是可以使用。这就很麻烦了。服务端根本不能控制。这时候你会记得session得好。

其他

还真没什么好说的,可能有人觉得JWT加密解密开销大、有人觉得JWT太长占空间、session太老了该让位了、JWT只需要存储Token在客户端方便、JWT加密感觉好安全不一而足……

对于以上的看别人博文没什么卵用,自己实现下就知道厉害了。

JWT变异之路(实现)

实现来讲的话有点后端开发基础的应该都知道怎么写代码在知道实现原理的情况下。这里不再讲述,要讲的是本人使用JWT用于个人博客遇到一些情况。在此记录,与君共勉之。

前提

首先轻轻松松实现了JWT。本人后端采用Koa2搭建。鉴权使用koa-jwt、生成token采用jsonwebtoken。npm就是这么方便啊。不过还是怀念当初驰骋j2ee的时候。言归正传。发现几个个很蛋疼的问题。

遇到的问题

1. 我什么服务端居然不能掌控全局,居然不能让禁止某个用户登录。这哪能忍。

好吧,绞尽脑汁,超越处女座忍受极限。我生成token返回前端时,将用户id作为key,token作为value(存token只是随意,这里只是举例)存在redis,且设置过期时间和token一致。每次前端请求时我都先和往常一般常规验证,ok之后继续解出用户id,查看redis有没有这条记录。有的话该干嘛干嘛,没有的话说明因为某种原因你被管理员kill掉了。乖乖重新登录或者申诉吧。

感觉还可以,虽然不再是无状态了,但是解决了问题不是,心里好受多了。但是发现想多了。

2. 这点其实是因为工作立马就想到了。当时公司要开发个联机帮助工具。就交给我全权开发。

当时开发完了有人反馈说是我写到一半有点事耽搁了下,然后退出了,这个不就白写了。好吧,想起自己的个人博客,虽然我肯定会做个keyup监测保存功能,但是有可能我访问着访问着就退出了。用户体验有木有啊。辣鸡有木有啊。

那就客户端加个刷新token策略咯。综合考虑之下打算认证时后端生成返回俩个token给前端:accesstoken、refreshtoken。前者用于访问鉴权,后者用于刷新token。区别在于前者过期时间短,后者过期时间长。具体时长自己开心就好。

然后现在就这样子了。比如我accesstoken过期时间30min,refreshtoken过期时间7d。在即将过期的时候(25min),我使用refreshtoken重新向服务端拉取新的accesstoken。你想顺带更新下refreshtoken也是可以的。看自己业务逻辑使用场景。当然也可以在过期时检测下refreshtoken有没有过期,没过期的话拉下新token。

以上就是本人遇到的俩个问题,结果最后发现我的JWT又变成Session。

后记

看的再多不如动手一次。因为会发现想象着很简单的东西实现起来完全脱离自己掌控。

(喜欢就转发或点赞哈~)

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180920A14UYP00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券