Token验证——JWT方法(明白了!好文章!!)
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:客户端使用用户名跟密码请求登录服务端收到请求,去验证用户名与密码验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里客户端每次向服务端请求资源的时候需要带着服务端签发的 Tok
简而言之,JWT就是一个加密的字符串,作为验证信息在计算机之间传递,只有可以访问持有对应正确的加密密钥的计算机才能对其进行解密,从而验证携带这个令牌(Token
)的请求是否合法。
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
- 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
JWT验证
JWT,读作:jot ,表示:JSON Web Tokens
JWT 标准的 Token 由三个部分组成:header.payload.signature
:
- header(头部)
- payload(数据)
- signature(签名)
中间用点分隔开,并且都会使用 Base64 编码,所以真正的 Token 看起来像这样:
eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
Header
每个 JWT token 里面都有一个 header,也就是头部数据。里面包含了使用的算法,这个 JWT 是不是带签名的或者加密的。主要就是说明一下怎么处理这个 JWT token 。
唯一在头部里面要包含的是 alg 这个属性,如果是加密的 JWT,这个属性的值就是使用的签名或者解密用的算法。如果是未加密的 JWT,这个属性的值要设置成 none。
eg:
{
"alg": "HS256"
}
意思是这个 JWT 用的算法是 HS256,在base64url编码之后变成
eyJhbGciOiJIUzI1NiJ9
Payload
Payload 里面是 Token 的具体内容,这些内容里面有一些是标准字段,你也可以添加其它需要的内容。
- iss:Issuer,发行者
- sub:Subject,主题
- aud:Audience,观众
- exp:Expiration time,过期时间
- nbf:Not before
- iat:Issued at,发行时间
- jti:JWT ID
两个自定义的字段,一个是 name ,还有一个是 admin 。
{
"iss": "ninghao.net",
"exp": "1438955445",
"name": "wanghao",
"admin": true
}
使用 base64url 编码以后就变成了这个样子:
eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ
Signature
JWT 的最后一部分是 Signature ,这部分内容有三个部分——
第一部分 :Base64 编码的header。
第二部分:Base64 编码的payload。
第三部分:再用加密算法加密一下,加密的时候要放进去一个 Secret ,这个相当于是一个密码,这个密码秘密地存储在服务端,不得泄露。
组成结构是这样子:
- header
- payload
- secret
const encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload);
// 这里的 HMACSHA256() 就是我们在第一部分定义的加密算法。
HMACSHA256(encodedString, 'secret');
Signature部分处理完成以后看起来像这样:
SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
最后这个在服务端生成并且要发送给客户端的 Token 看起来像这样:(由以上三部分组成)
eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
客户端收到这个 Token 以后把它存储下来,下回向服务端发送请求的时候就带着这个 Token 。服务端收到这个 Token ,然后进行验证,通过以后就会返回给客户端想要的资源。
验证流程:
- 在头部信息中声明加密算法和常量,然后把header使用json转化为字符串
- 在载荷中声明用户信息,同时还有一些其他的内容,再次使用json把在和部分进行转化,转化为字符串
- 使用在header中声明的加密算法来进行加密,把第一部分字符串和第二部分的字符串结合和每个项目随机生成的secret字符串进行加密,生成新的字符串,此字符串是独一无二的
- 解密的时候,只要客户端带着jwt来发起请求,服务端就直接使用secret进行解密,解签证解出第一部分和第二部分,然后比对第二部分的信息和客户端穿过来的信息是否一致。如果一致验证成功,否则验证失败。
工作方式:
举一个例子🌰就能够明白 JWT 在实际项目的使用方式了。
在任意系统中,用户首先都会要要登陆他的账户,他们会向服务发送账号密码,服务器验证通过之后,创建的成一个令牌(Token
),并返回给客户端,客户端保存这个令牌。以后客户端发出的所有请求都会携带这个令牌(客户端一般会将这个令牌放在请求头的 x-access-token
中)。
这里服务器创建的令牌就是上文所说的加密的字符串了。
特点:
- 三部分组成,每一部分都进行字符串的转化
- 解密的时候没有使用数据库,仅仅使用的是secret进行解密(减小服务器资源压力)
- Jwt使用的secret千万不能丢失
————————————————
节选自,对原文有增加:https://blog.csdn.net/weixin_43648017/article/details/111464021
更多推荐
所有评论(0)