我想每一个web开发者肯定都知道cookie和session。但是在这里我仍然想用自己的话来表述一下。
啥是session? 简单理解它就是由服务器创建并存储于服务器的一个比较特殊的map —> 除了可以像其他map一样存取数据,它还有过期时间、有一个唯一的id用于区分不同的session、而最最重要
的是在创建该session时,会同时创建一个cookie,cookie的key为JSESSIONID
,而cookie的value正是该session的id。
那啥又是cookie呢? 首先需要指明的一点是cookie是由服务器创建的,它其实也可以简单的理解成一个map,或者更确切点来说就是一个k-v形式的键值对。当http请求获得到响应后,浏览器就会将服务端创建的cookie保存到浏览器中,默认情况下当浏览器关闭时该cookie就不存在了,但是服务器可以设置cookie的存活时间,如果设置了cookie的存活时间,即使关了浏览器,如果没超过cookie的存活时间,再打开浏览器,该cookie仍然会存在。—> 但是要说明的一点是使用spring-security服务器在创建session时,好像
我们无法修改cookie的存活时间。
对HttpSession session = request.getSession();的深入理解。 作为java开发者应该都知道创建session时一般都会使用这个语句进行创建,但是人们通常对这句话的解释是如果服务器中有该request对应的session就取出,没有就新建一个session,却很少提及细节。我在这里试着
展开说一下:
JSESSIONID
的cookie,其value值正好与当前服务器中的某个session的id一致则取出该session;JSESSIONID
,value为该session的id的cookie并响应给浏览器。首先应该明确的一点是在没有cookie和session时,任意两次的http请求都是没有什么关系的,也就是大家平常说的http请求是无状态的。cookie和session为http之间的请求建立起了联系,具体的实现方式大体可分为如下几步:
JSESSIONID
,value为该session id的cookie响应给浏览器;至于为什么会出现token这种认证方式,以及它和cookie/session孰优孰劣等问题,这里不进行任何分析,请大家自行百度,这里只聊一下token的基本概念.
那token究竟是什么呢? 其实token就是由服务器生成的一个字符串,这里我大体按照自己的理解
讲讲普通的token
和JSON Web Token即jwt
这两种token的生成机制及它们在用户登陆中扮演的作用.
通过上面的描述可以看到这种token极其类似于session和创建该session时同步创建的cookie两者之和.
验证该token是不是本服务器发送给该用户的有效的token
,----> 并以此来判定是不是该用户的请求,且该请求有没有权限访问该服务器的api。 其实前面文章中介绍的用户名+密码登陆、短信登陆、第三方用户登陆都是基于cookie和session实现的,那如何做基于token的登陆认证呢?按照本文关于token的介绍,我觉得自己实现一个普通token
的生成、存储、发送给浏览器(或app)+验证随后请求中的token属于哪个用户这一套流程应该也不是不可能的。但更简单且可取的方式是我们使用别人造好的轮子
—> spring security oauth。
那spring security oauth是什么呢?
首先我们先看一下下面这幅图,想必看过我前面关于第三方登陆的文章的人肯定不陌生。之前讲第三方登陆时,我们的程序相当于第三方应用
,QQ、微信等是服务提供商
。当我们的服务需要请求服务提供商的某一个接口(获取用户信息的接口)时,我们需要先向它们的认证服务器申请token
,然后拿着token去它们的资源服务器
去请求它们的接口 —> 再之后,它们的资源服务器会拿着请求中的token去认证服务器进行验证该token是否合法有效 —> 如果是,我们的应用就可以调用到它们接口并获取到相应的数据了。
关于Oauth2协议可以参考一下我之前的一篇文章《spring-security进阶1—第三方登陆原理1【从常理出发来思考一下oauth2协议】》
spring security oauth的大致原理如下图。
但是开发基于token的认证我们不用让用户走4种授权模式中的任何一种,因为我们的目的就是在用户登陆时,如果用户信息校验(这里所说的用户校验其实就是指的我们前面文章里讲到的用户名+密码登陆、手机短信登陆和第三方登陆)成功了,我们就为该用户生成一个token并将其返回给用户 —> 用户接下来的每次请求再带着该token —> 我们只需要验证该token合法 —> 就可以让用户请求到我们接口的数据了。
因此我们可以对spring security oauth框架稍微进行如下改造,来完成基于token的认证方式的代码开发:
注意:
oauth协议中并没有规定token要怎么生成、存储和校验。spring security oauth提供了一个默认的实现,其基本原理大致
就是我在本文描述的普通的token。我会在接下来的文章里探索如何将其换成jwt。
既然要对spring security oauth框架进行修改,肯定要对spring security oauth框架有所了解,因此接下来几篇文章大致如下: