JWT 的简单了解

 

JWT:JSON Web Token

最近看一个项目,用到了JWT做身份验证,在此做一些笔记以及记录,以防止将来忘记,如有错误请指正。

一、JWT原理

     JWT的原理是,服务器认证以后生成一个JSON对象,发回给用户,像下面:

{
  "姓名": "张三",
  "角色": "管理员",
  "到期时间": "2019年7月1日0点0分"
}

  以后用户和服务端通信时,都要发送这个JSON对象 ,服务端完全只靠这个对象认定用户身份,为了防止数据被篡改,服务端生成这个对象时会加上签名。

服务器端不保存session数据,服务器变成无状态的了,从而比较容易实现扩展。

二、JWT使用场景

     1、授权(Authorization):这是使用JWT最常见的情况,一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌所允许的路由、服务和资源。单点登录是一种现在广泛使用JWT的功能,因为它的开销很小,能够在不用的域中轻松使用。

     2、信息交换(Information Exchange):JSON Web令牌是在各方之间安全传输信息的好方法。因为JWT可以签名 - 例如,使用公钥/私钥对 - 您可以确定发件人是他们所说的人。此外,由于使用标头和有效负载计算签名,您还可以验证内容是否未被篡改。

三、JWT令牌结构

   JWT的数据结构:

 JSON Web Token由(.)分割的三部分构成,分别为

1、Header(头)

    JWT头部分是一个描述JWT元数据的JSON对象,通常由两部分组成:token的类型,即JWT,和算法的名称(比如HMAC SHA256或者RSA等等)。形式如下

{
  "alg": "HS256",
  "typ": "JWT"
}

然后用Base64Url对这个JSON编码,得到JWT的第一部分

2、Payload(有效载荷)

   JWT的第二部分是有效载荷,其中包含声明(claims)。声明是关于实体(通常是用户)和其它数据的声明。声明由三种类型:registered、public、private。

1)  Registered claims: 这里有一组预定义的声明,不是强制的,但是建议使用,其中一些有

     iss(issuer ):签发人

     exp(expiration time):过期时间

     sub(subject):主题

     aud(audience):用户

     nbf(Not Before): 生效时间

     iat(Issued At): 签发时间

     jti(JWT ID): 编号

2)  Public claims: 可随意定义

3)Private claims: 用于在同意使用他们的各方之间共享信息,并不是注册的或公开的声明。

示例有效负载:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

然后有效负载通过Base64Url编码,得到JWT的第二部分。

注意:不要在payload和header中放置敏感信息,除非他们是加密的。

3、Signature(签名)

    Signature是对前两部分的签名,防止数据篡改。

    首先服务器端定义一个密钥(secret),用户不知道这个密钥。然后使用header里面指定的签名算法(默认是HMAC SHA256),按照下面公式产生签名:

HMACSHA256(Base64UrlEncode(header)+"."+Base64UrlEncode(payload)+"."+secret)

算出签名以后将Header、Payload、Signature用”.“拼接成字符串,然后返回给用户。 

四、JWT的使用方式

     客户端收到服务器返回的JWT,可以存储在cookie里面,也可以存储在localStorage。

此后,客户端每次和服务通信,都要带上这个JWT,你可以放到cookie里面自动发送,但是这样不能跨域,所以更好的做法是放到Http请求的头信息Authorization字段里面。

Authorization:Bearer <token>

另一种做法是,跨域的时候,JWT就放在POST请求的数据体里面。

五、JWT的几个特点

(1)JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。

(2)JWT 不加密的情况下,不能将秘密数据写入 JWT。

(3)JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。

(4)JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。

(5)JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。

(6)为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。

六、跨域认证的问题

     互联网服务验证用户信息的流程如下:     

     1、用户向服务器发送用户名和密码

     2、服务器验证通过后,将相关数据保存在当前会话中

     3、服务器向用户返回一个session_id,写入用户的cookie中

     4、后续用户的每次请求都会通过cookie,将session_id发送给服务器

     5、服务器根据session_id,找到之前保存的数据,得知用户身份

这种模式在于扩展性(scaling)不好,单机没有问题,但如果是服务器集群,或者是跨域的服务导向架构,就要求session数据共享,每台服务器上都能读取session。

举例来说,A 网站和 B 网站是同一家公司的关联服务。现在要求,用户只要在其中一个网站登录,再访问另一个网站就会自动登录,请问怎么实现?

一种解决方案是 session 数据持久化,写入数据库或别的持久层。各种服务收到请求后,都向持久层请求数据。这种方案的优点是架构清晰,缺点是工程量比较大。另外,持久层万一挂了,就会单点失败。

另一种方案是服务器索性不保存 session 数据了,所有数据都保存在客户端,每次请求都发回服务器。JWT 就是这种方案的一个代表。

七、JWT了解

     1、服务端是如何验证token的正确性?

           由于签名是由前两部分header、payload和密钥通过加密算法得到的,在服务端,可以解析到header、payload在和密钥(secret)通过加密算法得到的结果和token比较是否一致,不一致则说明内容有篡改,一致则说明用户信息正确。也有一种验证token是否有效的方法,根据token得到用户名,和系统从数据库中查到的用户名比较是否相同,如果相同并且时间不过期则验证成功。         

            也可验证token是否过期。根据expiration time验证是否过期。

参考连接:http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html

     https://baijiahao.baidu.com/s?id=1608021814182894637&wfr=spider&for=pc

     https://www.cnblogs.com/cjsblog/p/9277677.html 

     https://jwt.io/introduction/

发布了19 篇原创文章 · 获赞 15 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/minion_banana/article/details/89496764
jwt
今日推荐