JWT原理和简单应用

JWT认证登陆

最近在作一个审核系统,后台登陆用到JWT登陆认证,在此主要作个总结git

JWT是什么

Json web token (JWT), 根据官网的定义,是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准.该token被设计为紧凑且安全的,特别适用于分布式站点的单点登陆场景。JWT的声明通常被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也能够增长一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。github

为何使用JWT

此处主要和传统的session做对比,传统的session在服务器端须要保存一些登陆信息,一般是在内存中,在后端服务器是集群等分布式的状况下,其余主机没有保存这些信息,因此都须要经过一个固定的主机进行验证,若是用户量大,在认证这个点上容易造成瓶颈,是应用不易拓展。web

JWT原理

JWT由三个部分组成,用点号分割,看起来像是这样,JWT token自己没有空格换行等,下面是为了美观处理了下算法

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJpc3MiOiJsYWJzX3B1cmlmaWVyLWFwaS1wYW5lbCIsImlhdCI6MTU1Mjk3NTg3OCwiZXhwIjoxNTU1NTY3ODc4LCJhdWQiOiJodHRwOi8vZmYtbGFic19wdXJpZmllci1hcGktdGVzdC5mZW5kYS5pby9wcm9kL3YxL2F1dGgvand0Iiwic3ViIjoiMTUwMTM4NTYxMTg4NDcwNCIsInNjb3BlcyI6WyJyZWdpc3RlciIsIm9wZW4iLCJsb2dpbiIsInBhbmVsIl19.
m0HD1SUd30TWKuDQImwjIl9a-oWJreG7tKVzuGVh7e4
1.头部(Header)

Header部分是一个json,描述JWT的元数据,一般是下面这样json

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

alg表示签名使用的的算法,默认是HMAC SHA256,写成HS256, tye表示这个token的类型,JWT token统一使用JWT,上面这段Header生成的token是后端

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
2.负载(Payload)

官方规定了7个字段,解释以下api

  • iss: 签发人,能够填写生成这个token的ID等等,可选参数
  • sub: 该JWT所面向的客户,能够存储用户的account_id等等,可选
  • aud:该JWTtoken的接收方,能够填写生成这个token的接口URL,可是不强制,可选
  • exp: 过时时间,时间戳,整数,可选参数
  • iat:生成token的时间,unix时间,时间戳,可选参数
  • nbf(Not Before): 表示该token在此时间前不可用,验证不经过的意思,可选
  • jti: JWT ID,主要用来生成一次性token,可选的参数

除了官方以外,咱们还能够定义一部分自定义字段,可是考虑到BASE64是可逆的,因此不要放入敏感信息
下面是一个例子;跨域

{
  "iss": "labs_purifier-api-panel",
  "iat": 1552975878,
  "exp": 1555567878,
  "aud": "http://ff-labs_purifier-api-test.fenda.io/prod/v1/auth/jwt",
  "sub": "1501385611884704",
  "scopes": [
    "register",
    "open",
    "login",
    "panel"
  ]
}

上面这个Payload,通过BASE64加密后,生成的token是安全

eyJpc3MiOiJsYWJzX3B1cmlmaWVyLWFwaS1wYW5lbCIsImlhdCI6MTU1Mjk3NTg3OCwiZXhwIjoxNTU1NTY3ODc4LCJhdWQiOiJodHRwOi8vZmYtbGFic19wdXJpZmllci1hcGktdGVzdC5mZW5kYS5pby9wcm9kL3YxL2F1dGgvand0Iiwic3ViIjoiMTUwMTM4NTYxMTg4NDcwNCIsInNjb3BlcyI6WyJyZWdpc3RlciIsIm9wZW4iLCJsb2dpbiIsInBhbmVsIl19
3.签名(Signature)

Signature是对前面两部分生成的两段token的加密,使用的加密方式是Header里面指定的,此处是HS256,此时,须要一个秘钥,不能够泄露,大体过程以下:服务器

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

JWT的使用

JWT token 通常放在请求头里面,固然也能够放在cookie里面,可是放在cookie里面不能够跨域,例如:

Authorization: Bearer <token>

JWT在Python中的简单生成和验证

jwt库

生成token

def create_token():
    payload={
              "iss": "labs_purifier-api-panel",
              "iat": 1552975878,
              "exp": 1555567878,
              "aud": Config.AUDIENCE,
              "sub": "1501385611884704",
              "scopes": [
                "register",
                "open",
                "login",
                "panel"
              ]
            }
    token = jwt.encode(payload, Config.SECRET_KEY, algorithm='HS256')
    return True, {'access_token': token}

验证token

def verify_jwt_token(token):
    try:
        payload = jwt.decode(token, Config.SECRET_KEY,
                             audience=Config.AUDIENCE,
                             algorithms=['HS256'])
    except (ExpiredSignatureError, DecodeError):
        return False, token
    if payload:
        return True, jwt_model

须要注意的是,若是在生成的时候,加上了aud参数,验证的时候也要用上audience参数,而且值必须同样

相关文章
相关标签/搜索