正文开始前,先说一个自己的面试时被问的一个问题:说一下session+cookie认证和token认证的区别?
被问到“区别”这个关键词,前提是要对区别对象(至少两个)原理都有所了解才行,还记得n年前来上海这边找.net工作时面试的第一家公司做的笔试题,写出CLR和JVM的区别。。。em~扯远了好像。
说到session认证,如果公司的项目没有做前后端分离或者使用REST无状态风格接口,相信大多数还是使用此登录认证方式。其原理是用户登录成功后,服务器保存用户信息至内存,并向客户端浏览器返回sessionid,下次请求客户端使用cookie或者url重写向服务器发送sessionid进行用户登录验证。
关于token认证,可能知道其原理的会比较少,自己之前也仅停留在使用层面上,工作中像有使用Spring Security安全框架的token防止表单重复提交和跨站请求伪造攻击(CSRF),其安全性层面的原理是用户提交成功后,此次的token便失效,即使token被窃取,别人拿到的也只是一个已失效的token而已。但是关于token认证的流程和原理确实没去了解过,所以此篇就针对其原理性的知识点来了解下token认证方式。
什么是token?
token翻译过来的的意思就是“令牌”,正常是通过身份认证后由服务器端生成的一个字符串凭证,并将该字符串返回给客户端,此后该凭证用于客户端向服务器发送的请求校验,有效token允许访问,无效token则拒绝访问。
token的组成
这里拿token的一个子集JWT(JSON Web Token)的组成来说明,JWT是一个很长的字符串,中间用"."分隔
JWT的三个部分依次如下
Header(头部)
Payload(负载)
Signature(签名)
依次对这三个组成部分说明:
✦
Header
Header是一个JSON对象,描述JWT的元数据,格式如下:
{
"alg":
"HS256",
"typ":
"JWT"
}
alg属性表示签名的算法(algorithm),默认是HS256
typ表示token的类型
最后将上面的JSON对象使用Base64URL算法转成字符串。
✦
PayLoad
PayLoad同样也是一个JSON对象,用来存放实际需要传递的数据,JWT规定了7个官方字段:
除了官方字段,还可以在此自定义私有字段,可以利用记录用户相关信息
{
"id": "100",
"name": "haoxr",
"status": true
}
其中属性键值对称为claim,这部分数据默认是不加密的,不能将私密信息放入,最后将上面的JSON对象使用Base64URL算法转成字符串。
✦
Signature
Signature 部分是对前两部分的签名,防止数据篡改,需指定一个密钥secret,此密钥只有服务器知道,不能泄露。然后使用Header里alg属性指定的签名算法(默认是HMACSHA256),按照以下公式产生签名
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
算出签名后,将Header、Payload、Signature 三个部分使用符号“.”拼接起来的字符串返回给客户端。
token的认证流程
1.用户输入用户名和密码,向服务器发送登陆请求
2.服务器端进行用户认证,通过生成token,返回token给客户端
3.客户端收到token,将其存放在cookie或者LocalStorage
4.客户端向服务端请求会带着客户端签发的token
5.服务端收到请求,对token进行自定义规则验证,通过响应请求数据
session
认证的缺点
缺
token
认证的优势
优
像现在市面倡导的前后端分离还有接口的RESTFul架构风格设计等等,好像无一不在主导token认证将成为主流的服务端认证方式,所以本文就其原理性的知识点做了整理,下篇则是整合实战。因为最近工作刚好用到,就此机会做个总结吧。至于开篇的session+cookie认证和token认证的区别则在比对两种认证方式的优劣势说了差不多了。还有就是这个面试题连带着前后端分离一起被问到的,现在应该清楚面试官为什么会这样问了。。。