1. Introduction

Hello, I’m Angol!

In order to climb backward or limit the flow and throttling, most apis will perform permission authentication when writing interfaces at the back end. Data will be returned only when the authentication passes, that is, the data is normal and not expired. Otherwise, an error will be reported directly

This article uses Django as an example to talk about the operation of back-end JWT interface authentication

2. JWT is introduced

JWT, known as JSON Web Token, is a mainstream cross-domain authentication solution

The data structure consists of three parts, separated by **. ** in the middle

They are:

  • The Header in the head

  • Payload load

  • Signature Signature

# JWT data format # Composition: header. Payload.Signature Header.payload.SignatureCopy the code

Among them

Header is used to set the signature algorithm and token type. The default signature algorithm is HS256, and the token type can be set to JWT.

Payload Specifies the data to be transmitted, including the iss issuer, EXP expiration time, and IAT issue time

Signature is used to sign the Header and Payload. By default, the Signature algorithm specified in the Header is used

Payload. Signature # Header: {"alg": "HS256","typ": "JWT"} # Payload: iss, exp, iat Signature Signature = HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)Copy the code

PS: base64UrlEncode, compared with Base64 algorithm, will omit “=”, replace “+” with “-“, replace “/” with “_” in the result.

3. Practice

First, install the JWT dependency packages in the virtual environment

Pip3 install PyJwtCopy the code

Then, define a method to generate JWT tokens

Note that you need to specify the expiration time and encryption mode when generating a JWT Token

Import time import JWT from django.conf import Settings def generate_jWt_token (user): "" :return: Timestamp = int(time.time()) + 60 * 60 * 24 * 7 HS256 return jwt.encode({"userid": user.pk, "exp": timestamp}, settings.SECRET_KEY,'HS256')Copy the code

Next, write an authentication class

This class inherits from the base class “BaseAuthentication”, overcomes the internal function “authenticate()”, performs JWT decryption on the request parameters, and performs database query. Data will be returned only if the authentication succeeds, otherwise an exception will be thrown

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): "" 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 (" authentication exception!" ) # JWT decodes try: jwt_token = auth[1] jwt_info = jwt.decode(jwt_token, Settings. SECRET_KEY,'HS256') # Obtain userid userid = jwt_info.get("userid") user = User.objects.get(pk=userid) return user, jwt_token except Exception: Raise exceptions. AuthenticationFailed (" the user does not exist ") except JWT. ExpiredSignatureError: Raise exceptions. AuthenticationFailed (" sorry, the token has expired!" )Copy the code

Finally, in the ViewSet, you just need to specify the authentication list in the authentication_classes property

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

class GoodsViewSet(viewsets.ModelViewSet):
    # 所有商品数据
    queryset = Goods.objects.all()

    # 序列化
    serializer_class = GoodsSerializer

    # JWT授权
    authentication_classes = [JWTAuthentication]
Copy the code

4. The last

In actual projects, JWT tokens are usually generated during login. In subsequent interfaces, only JWT tokens need to be set in the request header to return data normally

import requests url = "***.***.****" payload={} headers = { 'AUTHORIZATION': 'jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyaWQiOiJVTmJCRTJTRlNndm5DU0c3amdQZGJVIiwiZXhwIjoxNjI2MDk5NDA5fQ.cxXsRulEWWQo tNpb7XwlZbISrrpb7rSRCjkLsyb8WDM' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text)Copy the code

If you think the article is good, please like, share, leave a message, because this will be my strongest power to continue to output more high-quality articles!