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!