{"id":9308,"date":"2024-05-13T10:22:35","date_gmt":"2024-05-13T02:22:35","guid":{"rendered":"\/?p=9308"},"modified":"2024-05-13T10:22:35","modified_gmt":"2024-05-13T02:22:35","slug":"python%e8%ba%ab%e4%bb%bd%e9%aa%8c%e8%af%81%e5%8c%85-authlib","status":"publish","type":"post","link":"\/?p=9308","title":{"rendered":"python\u8eab\u4efd\u9a8c\u8bc1\u5305\u2014\u2014Authlib"},"content":{"rendered":"<p>\u4f60\u662f\u5426\u538c\u5026\u4e86\u4e0d\u65ad\u5730\u4e3a\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5b9e\u73b0\u5404\u79cd\u590d\u6742\u7684\u8eab\u4efd\u9a8c\u8bc1\u534f\u8bae\uff1f<\/p>\n<p>\u6709\u6ca1\u6709\u60f3\u8fc7\u6709\u4e00\u6b3e\u4e07\u80fd\u94a5\u5319\uff0c\u80fd\u591f\u4e00\u6b21\u6027\u89e3\u51b3  OAuth 1, OAuth 2  \u548c OpenID Connect  \u7b49\u591a\u79cd\u8eab\u4efd\u9a8c\u8bc1\u4e0e\u6388\u6743\u95ee\u9898\uff1f<\/p>\n<p>\u5982\u679c\u4f60\u7684\u7b54\u6848\u662f\u80af\u5b9a\u7684\uff0c\u90a3\u4e48 <strong>Authlib<\/strong> \u6b63\u662f\u4f60\u7684\u6551\u661f\u3002\u5728\u8fd9\u4e2a\u52a8\u6001\u7684\u4e92\u8054\u7f51\u65f6\u4ee3\uff0c\u4fdd\u62a4\u7528\u6237\u6570\u636e\u7684\u91cd\u8981\u6027\u524d\u6240\u672a\u6709\uff0cAuthlib  \u63d0\u4f9b\u7684\u534f\u8bae\u652f\u6301\u548c\u5b89\u5168\u6027\u6b63\u662f\u6784\u5efa\u73b0\u4ee3\u5e94\u7528\u7684\u5fc5\u5907\u4e4b\u9009\u3002<\/p>\n<h3><strong>\u8ba4\u8bc6  Authlib<\/strong><\/h3>\n<p>Authlib  \u662f\u7531  Heapspace  \u548c\u4e00\u7fa4\u70ed\u5fc3\u8d21\u732e\u8005\u7ef4\u62a4\u7684\u5f3a\u5927  Python  \u8eab\u4efd\u9a8c\u8bc1\u5e93\u3002<\/p>\n<p>\u5728\u6570\u5b57\u751f\u6001\u7cfb\u7edf\u4e2d\uff0c\u590d\u6742\u7684\u534f\u8bae\u6807\u51c6\u5f80\u5f80\u8ba9\u4eba\u671b\u800c\u751f\u754f\uff0c\u4f46  Authlib  \u7684\u8bde\u751f\uff0c\u4f7f\u5f97\u5f00\u53d1\u8005\u53ef\u4ee5\u5c3d\u53ef\u80fd\u5c11\u7684\u4ee3\u7801\u6765\u5b9e\u73b0\u8fd9\u4e9b\u6807\u51c6\u3002<\/p>\n<p>\u4e0d\u540c\u4e8e  OAuthLib, PyJWT  \u7b49\u53ea\u63d0\u4f9b\u5355\u4e00\u534f\u8bae\u6216\u6807\u51c6\u652f\u6301\u7684\u5e93\uff0cAuthlib  \u96c6 OAuth 1&amp;2, OpenID Connect, JWT &amp; JWS\/JWE  \u7b49\u591a\u9879\u5173\u952e\u6280\u672f\u4e8e\u4e00\u4f53\uff0c\u56e0\u6b64\uff0c\u65e0\u8bba\u4f60\u5e0c\u671b\u5b9e\u73b0\u54ea\u79cd\u8eab\u4efd\u9a8c\u8bc1\uff0cAuthlib  \u90fd\u80fd\u4e3a\u4f60\u63d0\u4f9b\u4e00\u7ad9\u5f0f\u7684\u89e3\u51b3\u65b9\u6848\u3002<\/p>\n<p>\u9879\u76ee\u5730\u5740\uff1a<strong><a href=\"https:\/\/github.com\/lepture\/authlib\">https:\/\/github.com\/lepture\/authlib<\/a><\/strong><\/p>\n<h3><strong>\u5b89\u88c5<\/strong><\/h3>\n<p>\u5b89\u88c5  Authlib  \u4e0e\u5b89\u88c5\u5176\u4ed6  Python  \u5e93\u65e0\u5f02\uff0c\u4f60\u53ea\u9700\u8981\u7b80\u5355\u4e00\u884c\u547d\u4ee4\uff1a<\/p>\n<pre><code>pip install Authlib<\/code><\/pre>\n<p>\u8bb0\u5f97\u5728\u6267\u884c\u5b89\u88c5\u524d\u786e\u4fdd\u4f60\u7684  Python  \u7248\u672c\u662f  3.6 \u6216\u4ee5\u4e0a\u3002<\/p>\n<h3><strong>\u57fa\u7840\u529f\u80fd<\/strong><\/h3>\n<h4><strong>OAuth 2.0 \u7684\u5b9e\u73b0<\/strong><\/h4>\n<p>Authlib  \u63d0\u4f9b\u4e86\u4e00\u4e2a\u5e94\u5bf9\u4e25\u683c\u89c4\u8303\u7684  OAuth 2.0 \u5b9e\u73b0\u3002<\/p>\n<p>\u5b83\u4e0d\u4ec5\u652f\u6301\u57fa\u672c\u7684  access token\u3001refresh token  \u7684\u751f\u6210\u548c\u9a8c\u8bc1\uff0c\u8fd8\u652f\u6301  token  \u5185\u7701\u3001\u64a4\u9500\u7b49\u9ad8\u7ea7\u529f\u80fd\u3002<\/p>\n<p>\u4e0b\u9762\u662f\u4e00\u4e2a\u521b\u5efa  OAuth 2.0 \u5ba2\u6237\u7aef\u4f1a\u8bdd\u7684\u7b80\u5355\u793a\u4f8b\uff1a<\/p>\n<pre><code class=\"language-python\">from authlib.integrations.requests_client import OAuth2Session\n\nclient_id = &#039;your-client-id&#039;\nclient_secret = &#039;your-client-secret&#039;\ntoken_endpoint = &#039;https:\/\/your-provider\/oauth\/token&#039;\n\nclient = OAuth2Session(client_id, client_secret)\ntoken = client.fetch_token(token_endpoint)<\/code><\/pre>\n<p>\u8fd9\u91cc\u6211\u4eec\u5b9e\u4f8b\u5316\u4e86\u4e00\u4e2a <code>OAuth2Session<\/code> \u5bf9\u8c61\uff0c\u5e76\u7528\u5b83\u6765\u83b7\u53d6\u4ee4\u724c\u3002<\/p>\n<p>\u7b80\u5355\u660e\u4e86\uff0c\u4e0d\u662f\u5417\uff1f<\/p>\n<h4><strong>OpenID Connect  \u652f\u6301<\/strong><\/h4>\n<p>\u5bf9\u4e8e\u9700\u8981\u4f7f\u7528  OpenID Connect  \u8fdb\u884c\u7528\u6237\u8eab\u4efd\u8ba4\u8bc1\u7684\u5f00\u53d1\u8005\u6765\u8bf4\uff0c Authlib  \u63d0\u4f9b\u4e86\u5168\u9762\u7684\u534f\u8bae\u652f\u6301\u3002<\/p>\n<p>\u4f60\u53ef\u4ee5\u5f88\u5bb9\u6613\u5730\u96c6\u6210  Authlib  \u4e0e\u4f60\u7684\u5e94\u7528\uff0c\u4ee5\u4fbf\u8fdb\u884c\u7528\u6237\u767b\u5f55\u548c\u8eab\u4efd\u9a8c\u8bc1\u3002<\/p>\n<pre><code class=\"language-python\"># \u793a\u610f\u4ee3\u7801\uff0c\u5177\u4f53\u5b9e\u73b0\u53ef\u80fd\u6709\u6240\u4e0d\u540c \nfrom authlib.integrations.flask_client import OAuth\n\noauth = OAuth()\noauth.register(\n    &#039;auth0&#039;,\n    # \u914d\u7f6e\u9879...\n)\n\n@your_flask_app.route(&#039;\/login&#039;)\ndef login():\n    redirect_uri = url_for(&#039;authorize&#039;, _external=True)\n    return oauth.auth0.authorize_redirect(redirect_uri)\n\n@your_flask_app.route(&#039;\/authorize&#039;)\ndef authorize():\n    token = oauth.auth0.authorize_access_token()\n    userinfo = oauth.auth0.parse_id_token(token)\n    # \u5904\u7406\u767b\u5f55\u903b\u8f91...<\/code><\/pre>\n<h3><strong>\u9ad8\u7ea7\u529f\u80fd<\/strong><\/h3>\n<p>\u9664\u4e86\u57fa\u7840\u7684\u8eab\u4efd\u9a8c\u8bc1\u6d41\u7a0b\uff0cAuthlib  \u8fd8\u63d0\u4f9b\u4e86\u4e00\u7cfb\u5217\u7684\u5b89\u5168\u548c\u9ad8\u7ea7\u7279\u6027\uff0c\u5305\u62ec  JWS\/JWE\u3001JWT  \u7b49\uff0c\u5e2e\u52a9\u5f00\u53d1\u8005\u66f4\u597d\u5730\u4fdd\u62a4\u7528\u6237\u6570\u636e\u548c\u670d\u52a1\u5b89\u5168\u3002<\/p>\n<h4><strong>JSON Web Token (JWT) \u7684\u4f7f\u7528<\/strong><\/h4>\n<p>Authlib  \u7684 JWT  \u5b9e\u73b0\u6ee1\u8db3\u4e86\u591a\u9879\u884c\u4e1a\u89c4\u8303\uff0c\u5305\u62ec\u7b7e\u540d\uff08JWS\uff09\u548c\u52a0\u5bc6\uff08JWE\uff09\u3002<\/p>\n<p>\u8fd9\u610f\u5473\u7740\u4f60\u53ef\u4ee5\u975e\u5e38\u65b9\u4fbf\u7684\u751f\u6210\u548c\u9a8c\u8bc1  JWTs\uff0c\u800c\u4e0d\u5fc5\u62c5\u5fc3\u80cc\u540e\u590d\u6742\u7684\u5b9e\u73b0\u3002<\/p>\n<pre><code class=\"language-python\">from authlib.jose import jwt\n\nheader = {&#039;alg&#039;: &#039;HS256&#039;}\npayload = {&#039;user_id&#039;: 123, &#039;name&#039;: &#039;Alice&#039;}\nsecret = &#039;your-secret-key&#039;\n\n# \u751f\u6210  JWT\ntoken = jwt.encode(header, payload, secret)\nprint(token)\n\n# \u9a8c\u8bc1\u5e76\u89e3\u6790  JWT\ndecoded_payload = jwt.decode(token, secret)\nprint(decoded_payload)<\/code><\/pre>\n<p>\u8be6\u7ec6\u8bf4\u660e\u3001\u7528\u6cd5\u3001\u529f\u80fd\u7b49\uff0c\u8bf7\u53c2\u8003<strong>\u9879\u76ee\u6587\u6863<\/strong>\uff1a<strong><a href=\"https:\/\/docs.authlib.org\">https:\/\/docs.authlib.org<\/a><\/strong><\/p>\n<h3><strong>\u5b9e\u8df5<\/strong><\/h3>\n<p>\u4e3a\u4e86\u5de9\u56fa\u4f60\u5b66\u4e60\u7684\u77e5\u8bc6\uff0c\u8bd5\u7740\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\u64cd\u4f5c\u4e00\u904d\uff1a<\/p>\n<ol>\n<li>\u521b\u5efa\u4e00\u4e2a <code>OAuth2Session<\/code> \u5e76\u8bd5\u56fe\u8fde\u63a5\u5230\u4e00\u4e2a\u5b9e\u9645\u7684  OAuth 2.0 \u63d0\u4f9b\u8005\uff0c\u6bd4\u5982  Google  \u6216\u8005  GitHub\u3002<\/li>\n<li>\u5206\u522b\u5c1d\u8bd5\u751f\u6210\u548c\u9a8c\u8bc1\u4e00\u4e2a  JWT\uff0c\u4f53\u4f1a\u8fd9\u4e00\u8fc7\u7a0b\u7684\u7b80\u4fbf\u6027\u3002<\/li>\n<\/ol>\n<h3><strong>\u603b\u7ed3<\/strong><\/h3>\n<p>\u65e0\u8bba\u662f\u8eab\u4efd\u9a8c\u8bc1\u7684\u521d\u5b66\u8005\u8fd8\u662f\u8d44\u6df1\u4e13\u5bb6\uff0cAuthlib  \u4e3a Python  \u793e\u533a\u5e26\u6765\u4e86\u524d\u6240\u672a\u6709\u7684\u4e00\u7ad9\u5f0f\u89e3\u51b3\u65b9\u6848\uff0c\u5b83\u7684\u7075\u6d3b\u6027\u3001\u5b89\u5168\u6027\u548c\u6613\u7528\u6027\u8d4b\u4e88\u4e86\u5f00\u53d1\u8005\u5728\u6570\u5b57\u8eab\u4efd\u9a8c\u8bc1\u6d6a\u6f6e\u4e2d\u4e58\u98ce\u7834\u6d6a\u7684\u80fd\u529b\u3002<\/p>\n<p>\u5982\u679c\u4f60\u6b63\u5bfb\u627e\u4e00\u4e2a\u9ad8\u6548\u5b9e\u73b0  OAuth  \u548c OpenID Connect  \u670d\u52a1\u7684  Python  \u5e93\uff0c\u90a3\u4e48  Authlib  \u7edd\u5bf9\u503c\u5f97\u5c1d\u8bd5\u3002<\/p>\n<hr \/>\n<p>\u4f5c\u8005\u6c34\u5e73\u6709\u9650\uff0c\u6587\u4e2d\u96be\u514d\u5b58\u5728\u4e00\u4e9b\u758f\u6f0f\u6216\u9519\u8bef\uff0c\u6b22\u8fce\u53cd\u9988\u3001\u6307\u6b63\uff0c\u611f\u8c22\u652f\u6301\uff01<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4f60\u662f\u5426\u538c\u5026\u4e86\u4e0d\u65ad\u5730\u4e3a\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5b9e\u73b0\u5404\u79cd\u590d\u6742\u7684\u8eab\u4efd\u9a8c\u8bc1\u534f\u8bae\uff1f \u6709\u6ca1\u6709\u60f3\u8fc7\u6709\u4e00\u6b3e\u4e07\u80fd\u94a5\u5319\uff0c\u80fd\u591f\u4e00\u6b21\u6027\u89e3\u51b3 OAuth 1, OAuth 2   \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":[53],"tags":[],"_links":{"self":[{"href":"\/index.php?rest_route=\/wp\/v2\/posts\/9308"}],"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=9308"}],"version-history":[{"count":1,"href":"\/index.php?rest_route=\/wp\/v2\/posts\/9308\/revisions"}],"predecessor-version":[{"id":9309,"href":"\/index.php?rest_route=\/wp\/v2\/posts\/9308\/revisions\/9309"}],"wp:attachment":[{"href":"\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=9308"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=9308"},{"taxonomy":"post_tag","embeddable":true,"href":"\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=9308"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}