{"id":9284,"date":"2024-04-27T19:05:35","date_gmt":"2024-04-27T11:05:35","guid":{"rendered":"\/?p=9284"},"modified":"2024-04-27T19:06:54","modified_gmt":"2024-04-27T11:06:54","slug":"jwt%e6%8f%ad%e7%a7%98","status":"publish","type":"post","link":"\/?p=9284","title":{"rendered":"JWT\u63ed\u79d8"},"content":{"rendered":"<p>JSON Web Tokens\uff0c\u662f\u4e00\u79cd\u5f00\u53d1\u7684\u884c\u4e1a\u6807\u51c6 <a href=\"https:\/\/tools.ietf.org\/html\/rfc7519\">RFC 7519<\/a> \uff0c\u7528\u4e8e\u5b89\u5168\u7684\u8868\u793a\u53cc\u65b9\u4e4b\u95f4\u7684\u58f0\u660e\u3002\u76ee\u524d\uff0cjwt\u5e7f\u6cdb\u5e94\u7528\u5728\u7cfb\u7edf\u7684\u7528\u6237\u8ba4\u8bc1\u65b9\u9762\uff0c\u7279\u522b\u662f\u73b0\u5728\u524d\u540e\u7aef\u5206\u79bb\u9879\u76ee\u3002<\/p>\n<h3>1. jwt\u8ba4\u8bc1\u6d41\u7a0b<\/h3>\n<p><img src=\"https:\/\/lemon-guess.oss-cn-hangzhou.aliyuncs.com\/img\/425762-20191114064617993-2060294994.png\" alt=\"img\" \/><\/p>\n<p>\u5728\u9879\u76ee\u5f00\u53d1\u4e2d\uff0c\u4e00\u822c\u4f1a\u6309\u7167\u4e0a\u56fe\u6240\u793a\u7684\u8fc7\u7a0b\u8fdb\u884c\u8ba4\u8bc1\uff0c\u5373\uff1a\u7528\u6237\u767b\u5f55\u6210\u529f\u4e4b\u540e\uff0c\u670d\u52a1\u7aef\u7ed9\u7528\u6237\u6d4f\u89c8\u5668\u8fd4\u56de\u4e00\u4e2atoken\uff0c\u4ee5\u540e\u7528\u6237\u6d4f\u89c8\u5668\u8981\u643a\u5e26token\u518d\u53bb\u5411\u670d\u52a1\u7aef\u53d1\u9001\u8bf7\u6c42\uff0c\u670d\u52a1\u7aef\u6821\u9a8ctoken\u7684\u5408\u6cd5\u6027\uff0c\u5408\u6cd5\u5219\u7ed9\u7528\u6237\u770b\u6570\u636e\uff0c\u5426\u5219\uff0c\u8fd4\u56de\u4e00\u4e9b\u9519\u8bef\u4fe1\u606f\u3002<\/p>\n<p>\u4f20\u7edftoken\u65b9\u5f0f\u548cjwt\u5728\u8ba4\u8bc1\u65b9\u9762\u6709\u4ec0\u4e48\u5dee\u5f02\uff1f<\/p>\n<ul>\n<li>\n<p>\u4f20\u7edftoken\u65b9\u5f0f<\/p>\n<pre><code>\u7528\u6237\u767b\u5f55\u6210\u529f\u540e\uff0c\u670d\u52a1\u7aef\u751f\u6210\u4e00\u4e2a\u968f\u673atoken\u7ed9\u7528\u6237\uff0c\u5e76\u4e14\u5728\u670d\u52a1\u7aef(\u6570\u636e\u5e93\u6216\u7f13\u5b58)\u4e2d\u4fdd\u5b58\u4e00\u4efdtoken\uff0c\u4ee5\u540e\u7528\u6237\u518d\u6765\u8bbf\u95ee\u65f6\u9700\u643a\u5e26token\uff0c\u670d\u52a1\u7aef\u63a5\u6536\u5230token\u4e4b\u540e\uff0c\u53bb\u6570\u636e\u5e93\u6216\u7f13\u5b58\u4e2d\u8fdb\u884c\u6821\u9a8ctoken\u7684\u662f\u5426\u8d85\u65f6\u3001\u662f\u5426\u5408\u6cd5\u3002<\/code><\/pre>\n<\/li>\n<li>\n<p>jwt\u65b9\u5f0f<\/p>\n<pre><code>\u7528\u6237\u767b\u5f55\u6210\u529f\u540e\uff0c\u670d\u52a1\u7aef\u901a\u8fc7jwt\u751f\u6210\u4e00\u4e2a\u968f\u673atoken\u7ed9\u7528\u6237\uff08\u670d\u52a1\u7aef\u65e0\u9700\u4fdd\u7559token\uff09\uff0c\u4ee5\u540e\u7528\u6237\u518d\u6765\u8bbf\u95ee\u65f6\u9700\u643a\u5e26token\uff0c\u670d\u52a1\u7aef\u63a5\u6536\u5230token\u4e4b\u540e\uff0c\u901a\u8fc7jwt\u5bf9token\u8fdb\u884c\u6821\u9a8c\u662f\u5426\u8d85\u65f6\u3001\u662f\u5426\u5408\u6cd5\u3002<\/code><\/pre>\n<\/li>\n<\/ul>\n<h3>2. jwt\u521b\u5efatoken<\/h3>\n<h4>2.1 \u539f\u7406<\/h4>\n<p>jwt\u7684\u751f\u6210token\u683c\u5f0f\u5982\u4e0b\uff0c\u5373\uff1a\u7531 <code>.<\/code> \u8fde\u63a5\u7684\u4e09\u6bb5\u5b57\u7b26\u4e32\u7ec4\u6210\u3002<\/p>\n<pre><code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c<\/code><\/pre>\n<p>\u751f\u6210\u89c4\u5219\u5982\u4e0b\uff1a<\/p>\n<ul>\n<li>\n<p>\u7b2c\u4e00\u6bb5HEADER\u90e8\u5206\uff0c\u56fa\u5b9a\u5305\u542b\u7b97\u6cd5\u548ctoken\u7c7b\u578b\uff0c\u5bf9\u6b64json\u8fdb\u884cbase64url\u52a0\u5bc6\uff0c\u8fd9\u5c31\u662ftoken\u7684\u7b2c\u4e00\u6bb5\u3002<\/p>\n<pre><code>{\n\"alg\": \"HS256\",\n\"typ\": \"JWT\"\n}<\/code><\/pre>\n<\/li>\n<li>\n<p>\u7b2c\u4e8c\u6bb5PAYLOAD\u90e8\u5206\uff0c\u5305\u542b\u4e00\u4e9b\u6570\u636e\uff0c\u5bf9\u6b64json\u8fdb\u884cbase64url\u52a0\u5bc6\uff0c\u8fd9\u5c31\u662ftoken\u7684\u7b2c\u4e8c\u6bb5<\/p>\n<pre><code>{\n\"sub\": \"1234567890\",\n\"name\": \"John Doe\",\n\"iat\": 1516239022\n...\n}<\/code><\/pre>\n<\/li>\n<li>\n<p>\u7b2c\u4e09\u6bb5SIGNATURE\u90e8\u5206\uff0c\u628a\u524d\u4e24\u6bb5\u7684base\u5bc6\u6587\u901a\u8fc7<code>.<\/code>\u62fc\u63a5\u8d77\u6765\uff0c\u7136\u540e\u5bf9\u5176\u8fdb\u884c<code>HS256<\/code>\u52a0\u5bc6\uff0c\u518d\u7136\u540e\u5bf9<code>hs256<\/code>\u5bc6\u6587\u8fdb\u884cbase64url\u52a0\u5bc6\uff0c\u6700\u7ec8\u5f97\u5230token\u7684\u7b2c\u4e09\u6bb5\u3002<\/p>\n<pre><code>base64url(\n  HMACSHA256(\n    base64UrlEncode(header) + \".\" + base64UrlEncode(payload),\n    your-256-bit-secret (\u79d8\u94a5\u52a0\u76d0)\n  )\n)<\/code><\/pre>\n<\/li>\n<\/ul>\n<p>\u6700\u540e\u5c06\u4e09\u6bb5\u5b57\u7b26\u4e32\u901a\u8fc7 <code>.<\/code>\u62fc\u63a5\u8d77\u6765\u5c31\u751f\u6210\u4e86jwt\u7684token\u3002<\/p>\n<p><strong>\u6ce8\u610f<\/strong>\uff1abase64url\u52a0\u5bc6\u662f\u5148\u505abase64\u52a0\u5bc6\uff0c\u7136\u540e\u518d\u5c06 <code>-<\/code> \u66ff\u4ee3 <code>+<\/code> \u53ca <code>_<\/code> \u66ff\u4ee3 <code>\/<\/code> \u3002<\/p>\n<h4>2.2 \u4ee3\u7801\u5b9e\u73b0<\/h4>\n<p>\u57fa\u4e8ePython\u7684pyjwt\u6a21\u5757\u521b\u5efajwt\u7684token\u3002<\/p>\n<ul>\n<li>\n<p>\u5b89\u88c5<\/p>\n<p><code>pip3 install pyjwt<\/code><\/p>\n<\/li>\n<li>\n<p>\u5b9e\u73b0 <\/p>\n<pre><code class=\"language-python\">import jwt\nimport datetime\nfrom jwt import exceptions\n\nSALT = 'iv%x6xo7l7_u9bf_u!9#g#m*)*=ej@bek5)(@u3kh*72+unjv='\n\ndef create_token():\n\n  # \u6784\u9020header\n  headers = {\n      'typ': 'jwt',\n      'alg': 'HS256'\n  }\n  # \u6784\u9020payload\n  payload = {\n      'user_id': 1, # \u81ea\u5b9a\u4e49\u7528\u6237ID\n      'username': 'wupeiqi', # \u81ea\u5b9a\u4e49\u7528\u6237\u540d\n      'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=5) # \u8d85\u65f6\u65f6\u95f4\n  }\n\n  result = jwt.encode(payload=payload, key=SALT, algorithm=\"HS256\", headers=headers).decode('utf-8')\n  return result\n\nif __name__ == '__main__':\n  token = create_token()\n  print(token)<\/code><\/pre>\n<\/li>\n<\/ul>\n<h3>3.jwt\u6821\u9a8ctoken<\/h3>\n<p>\u4e00\u822c\u5728\u8ba4\u8bc1\u6210\u529f\u540e\uff0c\u628ajwt\u751f\u6210\u7684token\u8fd4\u56de\u7ed9\u7528\u6237\uff0c\u4ee5\u540e\u7528\u6237\u518d\u6b21\u8bbf\u95ee\u65f6\u5019\u9700\u8981\u643a\u5e26token\uff0c\u6b64\u65f6jwt\u9700\u8981\u5bf9token\u8fdb\u884c<code>\u8d85\u65f6<\/code>\u53ca<code>\u5408\u6cd5\u6027<\/code>\u6821\u9a8c\u3002<\/p>\n<p>\u83b7\u53d6token\u4e4b\u540e\uff0c\u4f1a\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\u8fdb\u884c\u6821\u9a8c\uff1a<\/p>\n<ul>\n<li>\u5c06token\u5206\u5272\u6210 <code>header_segment<\/code>\u3001<code>payload_segment<\/code>\u3001<code>crypto_segment<\/code> \u4e09\u90e8\u5206<\/li>\n<li>\u5bf9\u7b2c\u4e00\u90e8\u5206<code>header_segment<\/code>\u8fdb\u884cbase64url\u89e3\u5bc6\uff0c\u5f97\u5230<code>header<\/code><\/li>\n<li>\u5bf9\u7b2c\u4e8c\u90e8\u5206<code>payload_segment<\/code>\u8fdb\u884cbase64url\u89e3\u5bc6\uff0c\u5f97\u5230<code>payload<\/code><\/li>\n<li>\u5bf9\u7b2c\u4e09\u90e8\u5206<code>crypto_segment<\/code>\u8fdb\u884cbase64url\u89e3\u5bc6\uff0c\u5f97\u5230<code>signature<\/code><\/li>\n<li>\u5bf9\u7b2c\u4e09\u90e8\u5206<code>signature<\/code>\u90e8\u5206\u6570\u636e\u8fdb\u884c\u5408\u6cd5\u6027\u6821\u9a8c\n<ul>\n<li>\u62fc\u63a5\u524d\u4e24\u6bb5\u5bc6\u6587\uff0c\u5373\uff1a<code>signing_input<\/code><\/li>\n<li>\u4ece\u7b2c\u4e00\u6bb5\u660e\u6587\u4e2d\u83b7\u53d6\u52a0\u5bc6\u7b97\u6cd5\uff0c\u9ed8\u8ba4\uff1a<code>HS256<\/code><\/li>\n<li>\u4f7f\u7528 \u7b97\u6cd5+\u76d0 \u5bf9<code>signing_input<\/code> \u8fdb\u884c\u52a0\u5bc6\uff0c\u5c06\u5f97\u5230\u7684\u7ed3\u679c\u548c<code>signature<\/code>\u5bc6\u6587\u8fdb\u884c\u6bd4\u8f83\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre><code>import jwt\nimport datetime\nfrom jwt import exceptions\n\ndef get_payload(token):\n    &quot;&quot;&quot;\n    \u6839\u636etoken\u83b7\u53d6payload\n    :param token:\n    :return:\n    &quot;&quot;&quot;\n    try:\n        # \u4ecetoken\u4e2d\u83b7\u53d6payload\u3010\u4e0d\u6821\u9a8c\u5408\u6cd5\u6027\u3011\n        # unverified_payload = jwt.decode(token, None, False)\n        # print(unverified_payload)\n\n        # \u4ecetoken\u4e2d\u83b7\u53d6payload\u3010\u6821\u9a8c\u5408\u6cd5\u6027\u3011\n        verified_payload = jwt.decode(token, SALT, True)\n        return verified_payload\n    except exceptions.ExpiredSignatureError:\n        print(&#039;token\u5df2\u5931\u6548&#039;)\n    except jwt.DecodeError:\n        print(&#039;token\u8ba4\u8bc1\u5931\u8d25&#039;)\n    except jwt.InvalidTokenError:\n        print(&#039;\u975e\u6cd5\u7684token&#039;)\n\nif __name__ == &#039;__main__&#039;:\n    token = &quot;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NzM1NTU1NzksInVzZXJuYW1lIjoid3VwZWlxaSIsInVzZXJfaWQiOjF9.xj-7qSts6Yg5Ui55-aUOHJS4KSaeLq5weXMui2IIEJU&quot;\n    payload = get_payload(token)<\/code><\/pre>\n<h3>4. jwt\u5b9e\u6218<\/h3>\n<h4>4.1 django \u6848\u4f8b<\/h4>\n<p>\u5728\u7528\u6237\u767b\u5f55\u6210\u529f\u4e4b\u540e\uff0c\u751f\u6210token\u5e76\u8fd4\u56de\uff0c\u7528\u6237\u518d\u6b21\u6765\u8bbf\u95ee\u65f6\u9700\u643a\u5e26token\u3002<\/p>\n<p>\u6b64\u793a\u4f8b\u5728django\u7684\u4e2d\u95f4\u4ef6\u4e2d\u5bf9tokne\u8fdb\u884c\u6821\u9a8c\uff0c\u5185\u90e8\u7f16\u5199\u4e86\u4e24\u4e2a\u4e2d\u95f4\u4ef6\u6765\u652f\u6301\u7528\u6237\u901a\u8fc7\u4e24\u79cd\u65b9\u5f0f\u4f20\u9012token\u3002<\/p>\n<ul>\n<li><code>url<\/code>\u4f20\u53c2<br \/>\n<img src=\"https:\/\/lemon-guess.oss-cn-hangzhou.aliyuncs.com\/img\/425762-20191114065240778-1187572466.png\" alt=\"img\" \/><\/li>\n<li><code>Authorization<\/code>\u8bf7\u6c42\u5934<br \/>\n<img src=\"https:\/\/lemon-guess.oss-cn-hangzhou.aliyuncs.com\/img\/425762-20191114065312904-139529786.png\" alt=\"img\" \/><\/li>\n<\/ul>\n<p>\u6e90\u7801\u4e0b\u8f7d\uff1a<a href=\"https:\/\/pan.baidu.com\/s\/1ANibEXYocu6V1JfDUydRHw\">https:\/\/pan.baidu.com\/s\/1ANibEXYocu6V1JfDUydRHw<\/a><\/p>\n<h4>4.2 django rest framework \u6848\u4f8b<\/h4>\n<p>\u5728\u7528\u6237\u767b\u5f55\u6210\u529f\u4e4b\u540e\uff0c\u751f\u6210token\u5e76\u8fd4\u56de\uff0c\u7528\u6237\u518d\u6b21\u6765\u8bbf\u95ee\u65f6\u9700\u643a\u5e26token\u3002<\/p>\n<p>\u6b64\u793a\u4f8b\u5728drf\u7684\u8ba4\u8bc1\u7ec4\u4ef6\u4e2d\u5bf9token\u8fdb\u884c\u6821\u9a8c\uff0c\u5185\u90e8\u7f16\u5199\u4e86\u4e24\u4e2a\u8ba4\u8bc1\u7ec4\u4ef6\u6765\u652f\u6301\u7528\u6237\u901a\u8fc7\u4e24\u79cd\u65b9\u5f0f\u4f20\u9012token\u3002<\/p>\n<ul>\n<li><code>url<\/code>\u4f20\u53c2<\/li>\n<li><code>Authorization<\/code>\u8bf7\u6c42\u5934<\/li>\n<\/ul>\n<p>\u6e90\u7801\u4e0b\u8f7d\uff1a<a href=\"https:\/\/pan.baidu.com\/s\/14dxnH7YvVNVFwpHEjcBLbg\">https:\/\/pan.baidu.com\/s\/14dxnH7YvVNVFwpHEjcBLbg<\/a><\/p>\n<h4>4.3 flask \u6848\u4f8b<\/h4>\n<p>\u5728\u7528\u6237\u767b\u5f55\u6210\u529f\u4e4b\u540e\uff0c\u751f\u6210token\u5e76\u8fd4\u56de\uff0c\u7528\u6237\u518d\u6b21\u6765\u8bbf\u95ee\u65f6\u9700\u643a\u5e26token\u3002<\/p>\n<p>\u6b64\u793a\u4f8b\u5728flask\u7684before_request\u4e2d\u5bf9token\u8fdb\u884c\u6821\u9a8c\uff0c\u5185\u90e8\u7f16\u5199\u4e86\u4e24\u4e2a\u51fd\u6570\u6765\u652f\u6301\u7528\u6237\u901a\u8fc7\u4e24\u79cd\u65b9\u5f0f\u4f20\u9012token\u3002<\/p>\n<ul>\n<li><code>url<\/code>\u4f20\u53c2<\/li>\n<li><code>Authorization<\/code>\u8bf7\u6c42\u5934<\/li>\n<\/ul>\n<p>\u6e90\u7801\u4e0b\u8f7d\uff1a<a href=\"https:\/\/pan.baidu.com\/s\/13w8on_OBBxAd1Pp4KXETaQ\">https:\/\/pan.baidu.com\/s\/13w8on_OBBxAd1Pp4KXETaQ<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>JSON Web Tokens\uff0c\u662f\u4e00\u79cd\u5f00\u53d1\u7684\u884c\u4e1a\u6807\u51c6 RFC 7519 \uff0c\u7528\u4e8e\u5b89\u5168\u7684\u8868\u793a\u53cc\u65b9\u4e4b\u95f4\u7684\u58f0\u660e\u3002\u76ee\u524d\uff0cjwt\u5e7f\u6cdb\u5e94\u7528\u5728\u7cfb\u7edf\u7684\u7528\u6237   \u2026 &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0},"categories":[190],"tags":[],"_links":{"self":[{"href":"\/index.php?rest_route=\/wp\/v2\/posts\/9284"}],"collection":[{"href":"\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=9284"}],"version-history":[{"count":2,"href":"\/index.php?rest_route=\/wp\/v2\/posts\/9284\/revisions"}],"predecessor-version":[{"id":9286,"href":"\/index.php?rest_route=\/wp\/v2\/posts\/9284\/revisions\/9286"}],"wp:attachment":[{"href":"\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=9284"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=9284"},{"taxonomy":"post_tag","embeddable":true,"href":"\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=9284"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}