Bootstrap

JWT

1.什么是token

token的意思是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。

token是在服务端产生的。如果前端使用用户名和密码向服务端发送请求认证,服务端认证成功,那么在服务端会返回token给前端。

前端可以在每次请求的时候带上token证明自己的合法地位。如果token在服务端持久化,那他就是一个永久的身份令牌。

服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
  • 客户端使用用户名跟密码请求登录
  • 服务端收到请求,去验证用户名与密码
  • 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  • 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  • 5.客户端每次向服务端请求资源的时候需要带着服务端签发的 Token

2.什么是jwt

jwt,即JSON Web Token的缩写,是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方式,用于在各方之间作为JSON对象安全地传输信息。

jwt由header(头部)payload(数据)signature(签名)三部分组成,它们之间用.分开,并且都会使用 Base64 编码.

如:

eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc

第一个部分为Header,由两部分组成,类型和算法,例如

{
  "alg": "HS256", // 算法
  "typ": "JWT" // 类型
}

第二个部分为Payload,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。例如:

{
  iss (issuer):签发人
  exp (expiration time):过期时间
  sub (subject):主题
  aud (audience):受众
  nbf (Not Before):生效时间
  iat (Issued At):签发时间
  jti (JWT ID):编号    
}

除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。

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

请注意,对于token,此信息虽然可以防止被篡改,但任何人都可以读取。除非加密,否则不要将秘密信息放在JWT的Payload或Header元素中。

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

首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。

3.使用node签发token

(1)首先需要下载jwt的依赖包

npm install jsonwebtoken

(2) 引入依赖

const jwt = require('jsonwebtoken')

(3)创建一个payload对象,来存储用户信息


let payload = {
    id:"134567",
    name:"zhangsan"
}

(4)创建一个签名,即密钥

let seccret = "jwttoken"

(5)生成token

let token = jwt.sign(payload,seccret,{
    expiresIn:"1h" ,   //到期时间7d(7天) 12h  120=120ms 提供三种单位
    issuer:"zzuly"     //发行人
})

(6)解析token


jwt.verify(token,seccret,(error,decoded)=>{
    if(error){
        console.log(error)
        return error
    }
    console.log("校验",decoded)
})
;