JWT的定义及其组成

作者: codefine | 来源:发表于2017-02-20 00:10 被阅读3779次

    JWT的定义及其组成

    JWT(JSON Web Token)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

    一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。

    载荷(Payload)

    我们先将用户认证的操作描述成一个JSON对象。其中添加了一些其他的信息,帮助今后收到这个JWT的服务器理解这个JWT。

    {
        "sub": "1",
        "iss": "http://localhost:8000/auth/login",
        "iat": 1451888119,
        "exp": 1454516119,
        "nbf": 1451888119,
        "jti": "37c107e4609ddbcc9c096ea5ee76c667"
    }
    

    这里面的前6个字段都是由JWT的标准所定义的。

    sub: 该JWT所面向的用户
    iss: 该JWT的签发者
    iat(issued at): 在什么时候签发的token
    exp(expires): token什么时候过期
    nbf(not before):token在此时间之前不能被接收处理
    jti:JWT ID为web token提供唯一标识
    

    这些定义都可以在标准中找到。

    将上面的JSON对象进行base64编码可以得到下面的字符串:

    eyJzdWIiOiIxIiwiaXNzIjoiaHR0cDpcL1wvbG9jYWx
    ob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDUxODg4MTE5LCJleHAiOjE0NTQ1MTYxMTksIm5iZiI6MTQ1MTg4OD
    ExOSwianRpIjoiMzdjMTA3ZTQ2MDlkZGJjYzljMDk2ZWE1ZWU3NmM2NjcifQ
    

    这个字符串我们将它称作JWT的Payload(载荷)。

    如果你使用Node.js,可以用Node.js的包base64url来得到这个字符串:

    
    var base64url = require('base64url')
    var header = {
        "from_user": "B",
        "target_user": "A"
    }
    
    console.log(base64url(JSON.stringify(header)))
    
    

    注:Base64是一种编码,也就是说,它是可以被翻译回原来的样子来的。它并不是一种加密过程。
    头部(Header)

    JWT还需要一个头部,头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。这也可以被表示成一个JSON对象:

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

    在这里,我们说明了这是一个JWT,并且我们所用的签名算法(后面会提到)是HS256算法。

    对它也要进行Base64编码,之后的字符串就成了JWT的Header(头部):

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
    

    签名(签名)

    将上面的两个编码后的字符串都用句号.连接在一起(头部在前),就形成了:

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiaXNzIjoiaHR0cDpcL1wvbG9jYWx
    ob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDUxODg4MTE5LCJleHAiOjE0NTQ1MTYxMTksIm5iZiI6MTQ1MTg4OD
    ExOSwianRpIjoiMzdjMTA3ZTQ2MDlkZGJjYzljMDk2ZWE1ZWU3NmM2NjcifQ
    

    最后,我们将上面拼接完的字符串用HS256算法进行加密。在加密的时候,我们还需要提供一个密钥(secret):

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

    这样就可以得到我们加密后的内容:

    wyoQ95RjAyQ2FF3aj8EvCSaUmeP0KUqcCJDENNfnaT4
    

    这一部分又叫做签名。

    最后将这一部分签名也拼接在被签名的字符串后面,我们就得到了完整的JWT:

    
    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiaXNzIjoiaHR0cDpcL1wvbG9jYWx
    ob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDUxODg4MTE5LCJleHAiOjE0NTQ1MTYxMTksIm5iZiI6MTQ1MTg4OD
    ExOSwianRpIjoiMzdjMTA3ZTQ2MDlkZGJjYzljMDk2ZWE1ZWU3NmM2NjcifQ.wyoQ95RjAyQ2FF3aj8EvCSaUmeP0KUqcCJDENNfnaT4
    

    相关文章

      网友评论

        本文标题:JWT的定义及其组成

        本文链接:https://www.haomeiwen.com/subject/rrrswttx.html