浅谈使用Json Web Token和Cookie的利弊

Authentication

现在基本上有两种不同的方式来处理服务器端的认证(Authentication)问题。

  1. Cookie-Based Authentication:最常用的是利用cookie来存储认证信息,并包含在发送请求中用于服务器端的核查
  2. Token-Based Authentication:本文主要介绍的Token为基础的认证方式。

Json Web Token(JWT)

JWT是一个以JSON为基准的标准规范,通过JSON来传递消息,具体定义可以参见这里
JWT自身会携带所有的信息,包括payload和signature。
JWT常常通过HTTP的header来传送信息,同时也可以通过URL来传送。

JWT的构成

1
header.payload.signature

Header包含2部分。
typ定义类型为JWT,alg定义加密类型为HS256

1
2
3
4
{
"typ":"JWT",
"alg":"HS256"
}

通过Base64的转化得到第一部分

1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Payload

这部分由我们需要发送的数据内容构成

1
2
3
4
5
6
{
"iss": "chengpeng.me",
"exp": 144444444,
"user": "CP",
"email": "chengandpeng@gmail.com"
}

其中
iss: token的发行者
exp: 过期时间,必须在现在时间之后
其他一些声明
sub: token的主题
aud: token的接受者
nfb: 定义不可接受数据的时间
iat: JWT的声明时间

转换成Base64后得到第二部分

1
eyJpc3MiOiAiY2hlbmdwZW5nLm1lIiwiZXhwIjogMTQ0NDQ0NDQ0LCJ1c2VyIjogIkNQIiwiZW1haWwiOiJjaGVuZ2FuZHBlbmdAZ21haWwuY29tIn0=

Singnature

第三部分的签名由上面我们得到的header和payload的base64的字符串,通过.连接起来,然后使用HS256算法进行加密得到。

1
2
var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload);
HMACSHA256(encodedString, 'secret');

加密时必须定义一个加密字符串(本例中为’secret’),由服务端自行定义,计算后得到的结果是

1
183e996cf3ba65be2d31e6ea3d53d70942ded7a9b89bfdd7e47e38a554c3ff25

把这部分内容和前2个结果通过.符号接连起来就是我们的JWT了

1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiAiY2hlbmdwZW5nLm1lIiwiZXhwIjogMTQ0NDQ0NDQ0LCJ1c2VyIjogIkNQIiwiZW1haWwiOiJjaGVuZ2FuZHBlbmdAZ21haWwuY29tIn0=.183e996cf3ba65be2d31e6ea3d53d70942ded7a9b89bfdd7e47e38a554c3ff25

相比传统的Cookie,使用JWT有些什么好处呢?

  1. 跨域:JWT允许向任何服务器或者域名使用ajax,因为JWT是包含在http header中传送数据的
  2. 减轻服务端负担:比起使用session来保存cookie,JWT自身包含了所有信息,通过解密即可验证
  3. 安全性:因为无需使用cookie,就不必担心劫持cookie的CSRF攻击了
  4. 移动端:对于无法使用cookie的一些移动端,JWT能够正常使用

热评文章