前言
JSON Web Token是符合RFC7519标准的开放式行业标准方法,用于在双方之间安全地表示声明。
What is Jwt
Jwt可以分为三个部分, header
, payload
, signature
, 它们之前通过.
来分隔.
HEADER
描述生成signature
的具体算法。
{
“alg”: “HS256”,
“typ”: “JWT”
}
PAYLOAD
所有的Jwt验证的声明都存储在这里。SIGNATURE
是由header
和payload
派生的字段.
下面我们来简单说下signature
是如何产生的
用.合并
base64UrlEncode
后的header
和payload
base64UrlEncode(header) + “.” + base64UrlEncode(payload)
对上面的产生的值和一个
secret-key
做 Hash, 使用的算法会描述在HEADER
里.hash_value = hash([base64UrlEncode(header) + “.” + base64UrlEncode(payload)], secret-key)
然后再将上面产生的结果再进行一个
bash64UrlEncode
Signature = base64UrlEncode(hash_value)
注: 因为secret-key
仅有服务端知道,而且只能它可以基于一个有效的签名产生一个新的 token, 所以请你一定保护好secret-key
的安全。
how it work
Jwt可以通过很多种认证机制来接入应用程序,最常见的方式是在每一个请求体头部添加认证 token 信息。
// eg:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0I joxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
是否可以更安全
注: Jwt token
的payload是明文存储的,所以较敏感的信息(比如:内部ip等),不要放在payload里。
我们知道secret-key
对于我们而言很重要,倘若secret-key
会带来很大的安全隐患. 可以使用RS256
非对称加密算法通过私钥签发一个token, 公钥来验证token的有效性。 私钥只有服务端知道,公钥可以被app/client
,甚至可以被任何人访问.
对于三方客户端需要验证Jwt token
是否为它们签发的,使用非对称加密是有用的。 如果服务端使用对称加密(比如HS256
)签发Jwt token
, 如果三方客户端需要认证token的有效的话,就不得不共享secret-key
。这样也就增加了secret-key
泄漏的风险。
可能你会说,对于三方客户端接入的情况下,不验证token
的有效性不就不存在泄漏secret-key
的风险吗? okay, 我们下面来说下不验证的另一种风险:
服务端直接相信Jwt token
header里的数据,而不验证签发token使用算法的有效性,黑客可以修改Jwt token
header里的算法从RS256
至HS256
, 然后再用公钥为token生成一个HMAC签名。服务器现在会将此token视为使用“HS256”算法生成的token,并使用其公钥对其进行解码和验证。
另外: 避免被暴力破解,当使用HS256
的算法时,推荐使用256
字符作为secret-key
。
是否可以自动延长过期时间
如果你想延长token,Jwt token
自身并不能很好的解决这个问题,Auth0
则可以很好的解决这个问题。
你可以自定义一个刷新接口,当token快过期时,重新生成一个新的token并继续使用。
如何使用
你可以从这里Jwt.io获取到相应的签名及验证库
示例
这里提供了一个基于go语言的demo, 希望对你有所帮助。