如影随形

影子是一个会撒谎的精灵,它在虚空中流浪和等待被发现之间;在存在与不存在之间....

您现在的位置是:首页>laravel

什么是JWT

发布时间:2018-11-26编辑:wk 浏览(296)

    什么是JWT

    Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于分布式站点的单点登陆(SSO)场景。

    JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

    jwt的特点

    • 简洁(Compact): 可以通过URL,POST参数或者在HTTP header发送,因为数据量小,传输速度也很快

    • 自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库或缓存

    JWT是由三部分构成,将这三段信息文本用链接构成了JWT字符串。


    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vZGRrYXBwLmNjL2FwaS9hdXRoL

    2xvZ2luIiwiaWF0IjoxNTM2MDI3NDAzLCJleHAiOjE1Njc1NjM0MDMsIm5iZiI6MTUzNjAyNzQwMy

    wianRpIjoib2xNanZNZkJ0N25SdDZROCIsInN1YiI6ODc3LCJwcnYiOiI4NjY1YWU5Nzc1Y2YyNmY2Y

    jhlNDk2Zjg2ZmE1MzZkNjhkZDcxODE4In0.GMbX83GOlgl3KoGU226YUO5CKPewFj00lo-hbRkzYus


    jwt消息结构

    jwt有3个组成部分,分别是

    • 头部(header)

    • 载荷(payload)

    • 签证(signature)

    在Jwt字符串中两个点号把jwt分成了3部分

    Jwt的头部header承载两部分信息

    • 声明类型,这里是jwt

    • 声明加密的算法,通常直接使用HMACSHA256,就是HS256了

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

    然后将头部进行base64编码构成了第一部分

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

    Base64是一种用64个字符来表示任意二进制数据的方法

    Base64是一种任意二进制到文本字符串的编码方法,常用于在URL、Cookie、网页中传输少量二进制数据。

    载荷payload

    载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分

    • 标准中注册的声明

    • 公共的声明

    • 私有的声明 

     标注中注册的声明(建议不强制使用):

    • iss: jwt签发者

    • sub: jwt所面向的用户

    • aud: 接收jwt的一方

    • exp: jwt的过期时间,这个过期时间必须要大于签发时间

    • nbf: 定义在什么时间之前,该jwt都是不可用的.

    • iat: jwt的签发时间

    • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击

    payload-公共的声明 :

    公共的声明可以添加任何的信息。一般这里我们会存放一下用户的基本信息(非敏感信息)。

    payload-私有的声明 :

    私有声明是提供者和消费者所共同定义的声明。

    需要注意的是,不要存放敏感信息

    载荷内容:

    {"iss":"http://xxx.com","iat":1536027403,"exp":1567563403,"nbf":1536027403,"jti":"olMjvMfBt7nRt6Q8","sub":877,"prv":"8665ae9775cf26f6b8e496f86fa536d68dd71818"}

    sub和iat是标准声明,分别代表所面向的用户和jwt签发时间。

    签证:

    签证部分的信息有3个组成部分:

    • 头部-header (base64后的)

    • 载荷-payload (base64后的)

    • 密钥-secret

    然后HMACSHA256只有两个参数,

    • base64后的头部 + "." + base64后的载荷

    • 密钥-secret

    注意:secret是保存在服务器端的,jwt的签发也是在服务端的,secret就是用来进行jwt的签发和jwt的验证,所以它就是你服务端的私钥,在任何场景都不应该流露出去,一旦客户端得知这个secret,那就意味着客户端可以自我签发jwt了

    优点:

    因为json的通用性,所以JWT是可以跨语言支持的,像C#,JavaScript,NodeJS,PHP等许多语言都可以使用

    因为由了payload部分,所以JWT可以在自身存储一些其它业务逻辑所必要的非敏感信息

    便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的

    它不需要在服务端保存会话信息,所以它易于应用的扩展

    安全相关:

    不应该在jwt的payload部分存储敏感信息,因为该部分是客户端可解密的部分

    保护好secret私钥。该私钥非常重要

    如果可以,请使用https协议

    在Web应用中,别再把JWT当做session使用,绝大多数情况下,传统的cookie-session机制工作得更好

    JWT适合一次性的命令认证,颁发一个有效期极短的JWT,即使暴露了危险也很小,由于每次操作都会生成新的JWT,因此也没必要保存JWT,真正实现无状态。


关键字词:jwt php linux