{"id":815,"date":"2024-07-18T20:37:41","date_gmt":"2024-07-18T12:37:41","guid":{"rendered":"https:\/\/www.madbull.site\/?p=815"},"modified":"2024-07-30T11:19:54","modified_gmt":"2024-07-30T03:19:54","slug":"fastapi%e5%a2%9e%e5%8a%a0jwt%e9%aa%8c%e8%af%81%e5%8a%9f%e8%83%bd","status":"publish","type":"post","link":"https:\/\/www.madbull.site\/?p=815","title":{"rendered":"fastapi\u589e\u52a0jwt\u9a8c\u8bc1\u529f\u80fd"},"content":{"rendered":"\n<div class=\"wp-block-group is-layout-flow wp-block-group-is-layout-flow\">\n<p>fastapi\u7684\u4f7f\u7528\u5b9e\u4f8b\u53c2\u770b\u4e4b\u524d\u7684 <mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-accent-3-color\"><a href=\"https:\/\/www.madbull.site\/?p=565\"><strong>\u6587\u7ae0<\/strong><\/a> <\/mark><a href=\"https:\/\/www.madbull.site\/?p=565\">https:\/\/www.madbull.site\/?p=565<\/a> \uff0c\u4e0b\u8fb9\u7684\u793a\u4f8b\u662f\u5bf9 t1.py \u7684\u6539\u9020\uff0c\u589e\u52a0\u767b\u5f55\u8ba4\u8bc1\u3001token\u751f\u6210\u3001token\u9a8c\u8bc1\u3001\u6743\u9650\u9a8c\u8bc1\u529f\u80fd\u3002\u7ed3\u5408\u4e4b\u524d\u7684\u6587\u7ae0\uff0c\u66ff\u6362\u6389t1.py\u6587\u4ef6\uff0c\u5c31\u53ef\u4ee5\u642d\u5efa\u8d77\u6765\u6574\u4e2a\u9879\u76ee\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># -*- coding: utf-8 -*-\n\nfrom http import HTTPStatus\nfrom fastapi import status, Body, APIRouter, Request\nfrom fastapi.responses import JSONResponse, Response\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel\nfrom functools import wraps\nfrom passlib.context import CryptContext\n\nfrom jose import jwt\nfrom datetime import datetime, timedelta\nfrom typing import Any, Union\nimport traceback\n\n\n# \u521b\u5efa\u8def\u7531\ntest_router = APIRouter()\n\n# \u751f\u6210 \u5bc6\u7801\u6821\u9a8c\u5de5\u5177\np_ctx = CryptContext(schemes=&#91;\"bcrypt\"], deprecated=&#91;\"auto\"])\n\n# jwt \u8ba1\u7b97\u4f7f\u7528\u7684\u5bc6\u7801\nJWT_KEY = \"jfieOhoUHFjeifjeif232jmoi8\"\n# \u54c8\u5e0c\u7b97\u996d\nALGORITHM = \"HS256\"\n\n# \u6d4b\u8bd5\u6570\u636e\uff0c\u89d2\u8272\u5bf9\u5e94\u7684\u6743\u9650\nrole_dict = {\"admin\": &#91;\"\/tt\/test\/t1\", \"\/tt\/test\/t2\"]}\n\"\"\"\n * \u7b80\u5355\u5224\u65ad\u4e00\u4e0b\u89d2\u8272\u7684\u6743\u9650\n\"\"\"\ndef check_permission(req_path, role) :\n    if req_path in role_dict&#91;role] :\n        return True\n    else :\n        return False\n\n\"\"\"\n * \u767b\u5f55\u68c0\u67e5\u548c\u6743\u9650\u68c0\u67e5\n * 0 \u767b\u5f55\u6210\u529f\uff0c\u6743\u9650\u5141\u8bb8\n * 1 \u767b\u5f55\u8ba4\u8bc1\u5931\u8d25\n * 2 \u767b\u5f55\u6210\u529f\uff0c\u4f46\u662f\u6743\u9650\u4e0d\u6b63\u786e\n *\n\"\"\"\ndef jwt_auth_check(authorization, req_path ) :\n    # \u9a8c\u8bc1 jwt token \u662f\u5426\u6b63\u786e\u6216\u8005\u8d85\u65f6\u3002\n    try:\n        jwt_token = jwt.decode(authorization, JWT_KEY, ALGORITHM)\n    except :\n        # \u8d85\u65f6\u548c\u5176\u4ed6\u9519\u8bef\n        traceback.print_exc()\n        return 1\n    # \u9a8c\u8bc1\u662f\u5426\u5177\u6709\u8bbf\u95ee\u6743\u9650\n    ret = check_permission(req_path, jwt_token&#91;\"role\"])\n    if ret :\n        return 0\n    else :\n        return 2\n\n\n\"\"\"\n * \u767b\u5f55\u63d0\u4ea4\u7684\u6570\u636e\n\"\"\"\nclass Login(BaseModel):\n    username: str = \"&lt;not given>\"\n    passwd: str = \"&lt;not given>\"\n\n# \u83b7\u53d6\u771f\u5b9e\u5bc6\u7801\n# \u6b64\u5904\u9700\u8981\u4ece\u6587\u4ef6\u3001\u6570\u636e\u5e93\u6216\u8005\u5bc6\u7801\u5b58\u50a8\u7cfb\u7edf\u4e2d\uff0c\u6839\u636eusername\u83b7\u53d6\u5bc6\u7801\u7684hash\uff0c\u548c\u89d2\u8272\n# \u6b64\u5904\u4ec5\u6d4b\u8bd5\u7528\uff0c\u53ea\u7ed9\u51fa\u4e86 \"12345678\" \u8fd9\u4e2a\u5bc6\u7801\u7684 hash \u503c\u3002\n# hash\u7684\u751f\u6210\u65b9\u6cd5 p_ctx.hash(\"12345678\")\ndef get_pwdhash_and_role_by_username( username ) :\n    return \"\"\"$2b$12$va7WZCbCXkie01cntgUafO.BreMuQ2uAHblgmC3sM6yI\/5tPtnNqm\"\"\", \"admin\"\n\n\"\"\"\n * \u6784\u9020 jwt \u7684 token\n * \u9ed8\u8ba4 token 2\u5206\u949f\u8d85\u65f6\uff0c\u53ef\u4ee5\u5355\u72ec\u6307\u5b9a\n\"\"\"\ndef create_jwt_token(username, role, mnts : int = 2 ) :\n    expire = datetime.utcnow() + timedelta(minutes=mnts) \n    data = {\"exp\": expire, \"sub\": username, \"role\": role}\n    jwt_token = jwt.encode(data, JWT_KEY, algorithm=ALGORITHM)\n    return jwt_token\n\n\n\"\"\"\n * \u767b\u5f55\u63a5\u53e3\uff0c\u8d26\u53f7\u5bc6\u7801\u9a8c\u8bc1\u6210\u529f\u540e\uff0c\u751f\u6210 jwt \u7684 token \u8fd4\u56de\u7ed9\u5ba2\u6237\u7aef\n\"\"\"\n@test_router.post(\"\/login\", summary=u\"\u7b2c\u4e00\u4e2a\u6d4b\u8bd5\")\ndef login(lgn: Login= Body(...)) :\n    pwd_hash, role = get_pwdhash_and_role_by_username(lgn.username)\n    if pwd_hash is None :    # \u7528\u6237\u4e0d\u5b58\u5728\n        return shot_return(status.HTTP_400_BAD_REQUEST)\n    auth_rslt = p_ctx.verify(lgn.passwd, pwd_hash)\n    if auth_rslt is True :          # \u767b\u5f55\u6210\u529f\n        # \u521b\u5efatoken\n        jwt_token = create_jwt_token(lgn.username, role) ;\n        # \u6784\u9020\u8fd4\u56de\u503c\n        json_data = jsonable_encoder(jwt_token)\n        return JSONResponse(\n            status_code=status.HTTP_200_OK,\n            content = {\n                \"code\": status.HTTP_200_OK,\n                \"message\": \"Success\",\n                \"data\": {\n                    \"accessToken\": json_data,\n                    \"token_type\": \"bearer\"\n                }\n            }\n        )\n    else :\n        return shot_return(status.HTTP_400_BAD_REQUEST)\n\n\n# \u7b80\u77ed\u8fd4\u56de\u51fd\u6570\uff0c\u53ea\u8fd4\u56de http code \u548c\u8bf4\u660e\ndef shot_return(ret_st):\n    return JSONResponse(\n        status_code=ret_st,\n        content = {\n            \"code\": ret_st, \n            \"message\": HTTPStatus(ret_st).phrase\n        })\n\n\n\"\"\"\n * \u6784\u9020\u4e00\u4e2a\u88c5\u9970\u5668\uff0c\u7528\u6765\u68c0\u67e5\u662f\u5426\u5df2\u7ecf\u662f\u767b\u5f55\u72b6\u6001\n * \u6ce8\u610f\uff0c\u6b64\u88c5\u9970\u5668\u4fee\u9970\u7684\u51fd\u6570\uff0c\u6700\u540e\u4e00\u4e2a\u53c2\u6570\u5fc5\u987b\u662f Request \u5bf9\u8c61\n\"\"\"\ndef login_check(f) :\n    @wraps(f)\n    def is_logined(*args, **kwargs):\n        request = kwargs.get(\"request\")\n        # \u83b7\u53d6 header \u91cc\u7684 authorization \u5b57\u6bb5\n        authorization=request.headers.get(\"authorization\")\n        if authorization is None :\n            return shot_return(status.HTTP_401_UNAUTHORIZED)\n        else :\n            req_path = request.get('path')\n            jwt_auth_rslt = jwt_auth_check(authorization, req_path) \n            if jwt_auth_rslt == 0 :                 # 0 \u767b\u5f55\u6210\u529f\uff0c\u6743\u9650\u5141\u8bb8\n                return f(*args, **kwargs)\n            elif jwt_auth_rslt == 1 :               # 1 \u767b\u5f55\u8ba4\u8bc1\u5931\u8d25\n                return shot_return(status.HTTP_401_UNAUTHORIZED)\n            elif jwt_auth_rslt == 2 :               # 2 \u767b\u5f55\u6210\u529f\uff0c\u4f46\u662f\u6743\u9650\u4e0d\u6b63\u786e\n                return shot_return(status.HTTP_405_METHOD_NOT_ALLOWED) \n                \n    return is_logined\n\n\n\"\"\"\n * get\u8bf7\u6c42\u5904\u7406\n * \u7528login_check\u88c5\u9970\u5668\u505a\u4e86\u5904\u7406\uff0c\u5148\u9a8c\u8bc1\u767b\u5f55\u60c5\u51b5\uff0c\u548c\u6743\u9650\u5206\u914d\u60c5\u51b5\u3002\n\"\"\"\n@test_router.get(\"\/t1\", summary=u\"\u7b2c\u4e00\u4e2a\u6d4b\u8bd5\")\n@login_check\ndef t1(a: str = \"&lt;not given>\", b: str = \"&lt;not given>\", request: Request=None ) -> Response :\n    pstr = \"param a is &#91;\"+a+\"]; param b is &#91;\"+b+\"]\"\n    return JSONResponse(\n        status_code=status.HTTP_200_OK,\n        content = {\n            \"code\": \"1001\",\n            \"message\": \"hello , first fast api return\",\n            \"params\" : pstr,\n            \"request.headers\" : dict(request.headers)\n        })<\/code><\/pre>\n\n\n\n<div style=\"margin-top:var(--wp--preset--spacing--20);margin-bottom:var(--wp--preset--spacing--20);height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained\">\n<p>\u542f\u52a8<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"658\" height=\"149\" src=\"https:\/\/www.madbull.site\/wp-content\/uploads\/2024\/07\/22-4.png\" alt=\"\" class=\"wp-image-817\" srcset=\"https:\/\/www.madbull.site\/wp-content\/uploads\/2024\/07\/22-4.png 658w, https:\/\/www.madbull.site\/wp-content\/uploads\/2024\/07\/22-4-300x68.png 300w\" sizes=\"auto, (max-width: 658px) 100vw, 658px\" \/><\/figure>\n\n\n\n<div style=\"margin-top:var(--wp--preset--spacing--20);margin-bottom:var(--wp--preset--spacing--20);height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained\">\n<p>\u53d1\u8d77\u6d4b\u8bd5<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"353\" src=\"https:\/\/www.madbull.site\/wp-content\/uploads\/2024\/07\/11-6-1024x353.png\" alt=\"\" class=\"wp-image-816\" srcset=\"https:\/\/www.madbull.site\/wp-content\/uploads\/2024\/07\/11-6-1024x353.png 1024w, https:\/\/www.madbull.site\/wp-content\/uploads\/2024\/07\/11-6-300x104.png 300w, https:\/\/www.madbull.site\/wp-content\/uploads\/2024\/07\/11-6-768x265.png 768w, https:\/\/www.madbull.site\/wp-content\/uploads\/2024\/07\/11-6-1536x530.png 1536w, https:\/\/www.madbull.site\/wp-content\/uploads\/2024\/07\/11-6.png 1582w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<div style=\"margin-top:var(--wp--preset--spacing--20);margin-bottom:var(--wp--preset--spacing--20);height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained\">\n<p>\u670d\u52a1\u7aef\u65e5\u5fd7<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"661\" height=\"44\" src=\"https:\/\/www.madbull.site\/wp-content\/uploads\/2024\/07\/33-1.png\" alt=\"\" class=\"wp-image-818\" srcset=\"https:\/\/www.madbull.site\/wp-content\/uploads\/2024\/07\/33-1.png 661w, https:\/\/www.madbull.site\/wp-content\/uploads\/2024\/07\/33-1-300x20.png 300w\" sizes=\"auto, (max-width: 661px) 100vw, 661px\" \/><\/figure>\n\n\n\n<div style=\"margin-top:var(--wp--preset--spacing--20);margin-bottom:var(--wp--preset--spacing--20);height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>fastapi\u7684\u4f7f\u7528\u5b9e\u4f8b\u53c2\u770b\u4e4b\u524d\u7684 \u6587\u7ae0 https:\/\/www.madbull.site\/?p=565 \uff0c\u4e0b [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":548,"comment_status":"open","ping_status":"open","sticky":false,"template":"single-with-sidebar","format":"standard","meta":{"footnotes":""},"categories":[155,154],"tags":[179,334,142,336,338,337],"class_list":["post-815","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python","category-154","tag-fastapi","tag-jwt","tag-python","tag-token","tag-338","tag-337"],"_links":{"self":[{"href":"https:\/\/www.madbull.site\/index.php?rest_route=\/wp\/v2\/posts\/815","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.madbull.site\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.madbull.site\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.madbull.site\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.madbull.site\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=815"}],"version-history":[{"count":4,"href":"https:\/\/www.madbull.site\/index.php?rest_route=\/wp\/v2\/posts\/815\/revisions"}],"predecessor-version":[{"id":919,"href":"https:\/\/www.madbull.site\/index.php?rest_route=\/wp\/v2\/posts\/815\/revisions\/919"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.madbull.site\/index.php?rest_route=\/wp\/v2\/media\/548"}],"wp:attachment":[{"href":"https:\/\/www.madbull.site\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=815"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.madbull.site\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=815"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.madbull.site\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=815"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}