NodeJS中jwt的使用

2020-11-25 10:01发布

一、什么是jwt?

jwt的全称是JSON WEB Token,是一种基于JSON的、用于在网络上声明某种主张的令牌(token)。JWT通常由三部分组成: 头信息(header), 消息体(payload)和签名(signature)。

二、为什么要使用jwt?

由于众所周知的原因,http协议本身是一种无状态的协议,而我们在开发过程中,经常需要解决前后端身份识别的问题。在以前的开发中,我们经常使用session或者cookie来解决这个问题。但是,在使用Session时,每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。而如果用cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。所有,我们可以使用jwt来解决这个问题。

三、如何使用jwt?

JWT通常由三部分组成: 头信息(header), 消息体(payload)和签名(signature)。

头信息(header)指定了该JWT使用的签名算法:

    let header = {
        'typ': 'jwt',
        'alg': 'HS256'          //声明加密的算法 通常直接使用 HMAC SHA256
    }

消息体中包含了JWT的意图:

这些意图包含三个部分:

    1)标准中注册的声明

    2)公共的声明

    3)私有的声明

不过,经常只声明标准部分即可,例如:

    let playload = {
        iat: null,
        exp: null,
        // iat: Date.now(),                               //签发时间
        // exp: Date.now() + 1000 * 10 * 60,               //过期时间    10分钟
        get iat() {
            return Date.now()
        },
        get exp() {
            return Date.now() + 1000 * 10 * 60
        }
    }

注:其中的iat:指jwt的签发时间。exp指 jwt的过期时间,这个过期时间必须要大于签发时间


jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

    1)header (base64后的)

    2)payload (base64后的)

    3)secret

签证的生成,需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分,例如:

    let key="ujiuye";//秘钥
    
    let unsignedToken = encodeBase64(header) + '.' + encodeBase64(payload)    
    
    let signature = hs256(key, unsignedToken);//生成加密的签证

将base64编码的header和playload以及签证,这三部分用.连接成一个完整的字符串,构成了最终的jwt,例如:

    let h = encodeBase64(header);//base64编码的header
    
    let p = encodeBase64(payload);//base64编码的playload
        
    let s = encodeBase64(signature);//base64编码的签证
           
    let token = `${h}.${p}.${s} `

然后就可以在服务器端将签发好的jwt发送给客户端,客户端请求服务器时,即可以在header中携带jwt,然后服务端使用自己保存的key计算、验证签名以判断该JWT是否可信