1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        5 分鐘,快速入門 Python JWT 接口認(rèn)證

        共 6439字,需瀏覽 13分鐘

         ·

        2021-09-11 01:46




        1. 前言

        大家好,我是安果!

        為了反爬或限流節(jié)流,后端編寫接口時,大部分 API 都會進(jìn)行權(quán)限認(rèn)證,只有認(rèn)證通過,即:數(shù)據(jù)正常及未過期才會返回數(shù)據(jù),否則直接報錯

        本篇文章以 Django 為例,聊聊后端 JWT 接口認(rèn)證的操作流程

        2. JWT 介紹

        JWT 全稱為 JSON Web Token,是目前主流的跨域認(rèn)證解決方案

        數(shù)據(jù)結(jié)構(gòu)由 3 部分組成,中間由「 . 」分割開

        它們分別是:

        • Header 頭部

        • Payload 負(fù)載

        • Signature 簽名

        # JWT 數(shù)據(jù)的格式
        # 組成方式:頭部.負(fù)載.簽名
        Header.Payload.Signature

        其中

        Header 用于設(shè)置簽名算法及令牌類型,默認(rèn)簽名算法為 「 HS256 」,令牌類型可以設(shè)置為「 JWT

        Payload 用于設(shè)置需要傳遞的數(shù)據(jù),包含:iss 簽發(fā)人、exp 過期時間、iat 簽發(fā)時間等

        Signature 用于對 Header 和 Payload 進(jìn)行簽名,默認(rèn)使用的簽名算法為 Header 中指定的算法

        # JWT 數(shù)據(jù)組成
        # Header. Payload. Signature
        # Header:{ "alg""HS256","typ""JWT"}
        # Payload:iss、exp、iat等
        # Signature:簽名
        Signature = HMACSHA256(
          base64UrlEncode(header) + "." +
          base64UrlEncode(payload),
          secret)

        PS:base64UrlEncode 相比 Base64 算法,會將結(jié)果中的「 = 」省略、「 + 」替換成「 - 」、「 / 」替換成「 _ 」

        3. 實戰(zhàn)一下

        首先,在虛擬環(huán)境中安裝 JWT 依賴包

        # 安裝jwt依賴包
        pip3 install pyjwt

        然后,定義一個方法用于生成 JWT Token

        需要注意的是,生成 JWT Token 時需要指定過期時間、加密方式等

        import time
        import jwt
        from django.conf import settings

        def generate_jwt_token(user):
            """
            生成一個JWT Token
            :param user:
            :return:
            """

            # 設(shè)置token的過期時間戳
            # 比如:設(shè)置7天過期
            timestamp = int(time.time()) + 60 * 60 * 24 * 7

            # 加密生成Token
            # 加密方式:HS256
            return jwt.encode({"userid": user.pk, "exp": timestamp}, settings.SECRET_KEY,'HS256')

        接著,編寫一個認(rèn)證類

        該類繼承于「 BaseAuthentication 」基類,重寫內(nèi)部函數(shù)「 authenticate() 」,對請求參數(shù)進(jìn)行 JWT 解密,并進(jìn)行數(shù)據(jù)庫查詢,只有認(rèn)證通過才返回數(shù)據(jù),否則拋出異常

        import time

        import jwt
        from django.conf import settings
        from django.contrib.auth import get_user_model
        from rest_framework import exceptions
        from rest_framework.authentication import BaseAuthentication, get_authorization_header

        User = get_user_model()

        class JWTAuthentication(BaseAuthentication):
            """自定義認(rèn)證類"""

            keyword = 'jwt'
            model = None

            def get_model(self):
                if self.model is not None:
                    return self.model
                from rest_framework.authtoken.models import Token
                return Token

            """
            A custom token model may be used, but must have the following properties.

            * key -- The string identifying the token
            * user -- The user to which the token belongs
            """


            def authenticate(self, request):
                auth = get_authorization_header(request).split()

                if not auth or auth[0].lower() != self.keyword.lower().encode():
                    return None

                if len(auth) !=2:
                    raise exceptions.AuthenticationFailed("認(rèn)證異常!")

                # jwt解碼
                try:
                    jwt_token = auth[1]
                    jwt_info = jwt.decode(jwt_token, settings.SECRET_KEY,'HS256')

                    # 獲取userid
                    userid = jwt_info.get("userid")

                    # 查詢用戶是否存在
                    try:
                        user = User.objects.get(pk=userid)
                        return user, jwt_token
                    except Exception:
                        raise exceptions.AuthenticationFailed("用戶不存在")
                except jwt.ExpiredSignatureError:
                    raise exceptions.AuthenticationFailed("抱歉,該token已過期!")

        最后,在視圖集 ViewSet 中,只需要在屬性「 authentication_classes 」中指定認(rèn)證列表即可

        from rest_framework import viewsets
        from .models import *
        from .serializers import *
        from .authentications import *

        class GoodsViewSet(viewsets.ModelViewSet):
            # 所有商品數(shù)據(jù)
            queryset = Goods.objects.all()

            # 序列化
            serializer_class = GoodsSerializer

            # JWT授權(quán)
            authentication_classes = [JWTAuthentication]

        4. 最后

        在實際項目中,一般在登錄的時候生成 JWT Token,后續(xù)接口中只需要在請求頭中設(shè)置 JWT Token 即可正常返回數(shù)據(jù)

        import requests

        url = "***.***.****"

        payload={}
        headers = {
          'AUTHORIZATION''jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyaWQiOiJVTmJCRTJTRlNndm5DU0c3amdQZGJVIiwiZXhwIjoxNjI2MDk5NDA5fQ.cxXsRulEWWQotNpb7XwlZbISrrpb7rSRCjkLsyb8WDM'
        }

        response = requests.request("GET", url, headers=headers, data=payload)
        print(response.text)

        如果你覺得文章還不錯,請大家 點贊、分享、留言 下,因為這將是我持續(xù)輸出更多優(yōu)質(zhì)文章的最強(qiáng)動力!

        瀏覽 33
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            中文字幕第28页 | 老女人色一区二区三区视频 | 国产成人毛片无码内谢 | 在线视频精品播放 | 嗯额宫交太长了高hhh | 成人无码高清免费视频 | 皇后高h喷水荡肉np | 少妇放荡的呻吟干柴烈火动态图 | 全部免费A片在线在线观看 | 91偷拍广州老熟女合集 |