当前位置:网站首页>JWT certification used in DRF
JWT certification used in DRF
2022-07-07 09:12:00 【FOR. GET】
Usage scenarios of common status codes
| Status code | Use scenarios |
|---|---|
| 200 | Service request succeeded , And responded to the data , Modification is also |
| 201 | New data succeeded , For new resources |
| 204 | Used to delete content |
| 301 | Permanent redirection |
| 400 | route 、? Query parameters , Request header , Error in request body parameter |
| 401 | The current request requires user login authentication , Login failed , Or not logged in |
| 403 | No access , Please contact the Administrator |
| 404 | request was aborted , The resource expected by the request was not found on the server . |
One 、 Traditional based token authentication
Traditional based token The certification process : The user login , The server gives the returned token, And will token Save on the server , Visit again later , Need to carry token, Server acquisition token after , Then go to the database to get token To verify that .
- register DRF application
# settings.py
# Application definition
INSTALLED_APPS = [
...
'rest_framework',
]
- Write a user model
# models.py
from django.db import models
# Create your models here.
class UserInfo(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=32)
token = models.CharField(max_length=128,null=True,blank=True)
- Database migration
# shell Command line
python manage.py makemigrations
# python manage.py check Check whether there are errors in database migration
python manage.py migrate
- Authoring views
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from user.models import UserInfo
import uuid
class LoginView(APIView):
""" The user login """
def post(self,request,*args,**kwargs):
user = request.data.get('username')
pwd = request.data.get('password')
user_obj = UserInfo.objects.filter(username=user,password=pwd).first()
if not user_obj:
return Response({
'code':401,'error':' Wrong user name or password '})
# Simulation generated token
user_token = str(uuid.uuid4())
# Save the generated token, Used for subsequent verification
user_obj.token = user_token
user_obj.save()
return Response({
'code':201,'token':user_token})
class IndexView(APIView):
# Judge to carry token Whether to take effect
def get(self,request,*args,**kwargs):
token = request.query_params.get('token')
if not token:
return Response({
"code":401,"error":" Log in successfully before accessing "})
user_token = UserInfo.objects.filter(token=token).first()
if not user_token:
return Response({
"code":401,'error':"token Has lapsed "})
return Response(f" Successfully logged in , welcome {
user_token.username}!")
- Configure the routing
# urls.py
from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from user.views import LoginView,IndexView
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', LoginView.as_view()),
path('index/', IndexView.as_view()),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Data stored in the table in advance , For simulation verification

post Request user name and password

- Access page


Two 、DRF Use in pyjwt To write JWT authentication
JWT The full name is Json Web Token, Commonly used for user authentication ( For front and rear end separation 、 Wechat applet 、app Development )
JWT The certification process : For logging in , The server returns a token( Not saved in the server ), Then the user will visit , Need to carry token, Do it again token The check . from https://jwt.io/ I saw it on the official website JWT The string is shown in the following figure :

- The user submits the user name and password to the server , If login is successful , Use JWT Create a token Values are as follows
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- The first part of the header is usually (HEADER) It's made up of two parts : Type of token , namely JWT, And the signature algorithm being used , for example HMAC SHA256 or RSA.
example :{ "alg": "HS256", "typ": "JWT" }- The second part is the load (PYLOAD), It contains a statement . Declarations are about entities ( Usually the user ) And statement of additional data . There are three types : Registration statement 、 Public and private statements . Registration statement : These are a set of predefined declarations , These statements are not mandatory , It's recommended , To provide a useful set of 、 Interoperable claims . Some of them are :iss( publisher )、exp( Due time )、sub( The theme )、aud( Audience ) etc. .( Please note that , The declaration name has only three characters , because JWT It's compact .) Public statement : These can be used by JWT People are defined at will . But to avoid conflict , They should be IANA JSON Web Token Registry In the definition of , Or defined as containing an anti-collision namespace URI. Private statement : These custom declarations are created to share information between parties who agree to use them , These statements are neither registration statements nor public statements .
example ( Don't add sensitive information ):{ "sub": "1234567890", "name": "John Doe", "admin": true }- The third part is signature (SIGN), To create a signature section , You have to get the encoded header 、 Encoded payload 、 Secret 、 The algorithm specified in the header , And sign it .
example :HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
- When users visit in the future , Need to carry Token, The back end needs to be right token check
- First step : obtain Token, Yes Token For cutting
- The second step : Go on to the second paragraph base64url Decrypt , And get the payload Information , test token Has it timed out
- The third step : hold 1,2, Partial splicing , Re execution Heade Encryption algorithm encryption , And judge with the signature , Equal means that the certificate is passed .
2.1 JWT Authentication implementation
- install pyjwt, Or other ways l link
pip install pyjwt
- Because there is no need to save the database , Make the following modifications .
from rest_framework.views import APIView
from rest_framework.response import Response
from user.models import UserInfo
import uuid
from django.conf import settings
class LoginView(APIView):
""" The user login """
def post(self,request,*args,**kwargs):
user = request.data.get('username')
pwd = request.data.get('password')
user_obj = UserInfo.objects.filter(username=user,password=pwd).first()
if not user_obj:
return Response({
'code':401,'error':' Wrong user name or password '})
import jwt
import datetime
salt = settings.SECRET_KEY
# structure Header, The default is as follows
headers = {
'typ':'jwt',
'alg':'HS256'
}
# structure Payload
payload = {
'user_id':user_obj.pk,# Custom user ID
'username':user_obj.username,# Custom user name
'exp':datetime.datetime.utcnow()+datetime.timedelta(minutes=1),# Set timeout ,1min
}
jwt_token = jwt.encode(headers=headers,payload=payload,key=salt,algorithm='HS256')
return Response({
'code':200,'token':jwt_token})
# {"username":"admin","password":"admin123"}
class IndexView(APIView):
def get(self,request,*args,**kwargs):
token = request.query_params.get('token')
if not token:
return Response({
"code":401,"error":" Log in successfully before accessing "})
# cutting
# Decrypt payload, Judge whether it is overdue
# Verify the legitimacy of the third paragraph
import jwt
salt = settings.SECRET_KEY
error = ""
try:
# from token In order to get payload【 Don't verify validity 】
# unverified_payload = jwt.decode(token, None, False)
# print(unverified_payload)
# from token In order to get payload【 Verify legitimacy 】
payload = jwt.decode(jwt=token, key=salt, algorithms=["HS256"])
print(payload)
return Response(f" Successfully logged in , welcome !")
except jwt.ExpiredSignatureError:
error = "token Has lapsed "
return Response({
"code": 401, "error": error})
except jwt.DecodeError:
error = "token Authentication failed "
return Response({
"code": 401, "error": error})
except jwt.InvalidTokenError:
error = " illegal token"
return Response({
"code": 401, "error": error})
2.2 JWT combination BaseAuthentication Use
- Create a new file to identify whether the function module is authenticated
# user/extensions/jwt_authenticate.py
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from django.conf import settings
class JWTQueryParamsAuthentication(BaseAuthentication):
def authenticate(self, request):
token = request.query_params.get('token')
print(token)
if not token:
raise AuthenticationFailed({
"code": 401, "error": " Log in successfully before accessing "})
# cutting
# Decrypt payload, Judge whether it is overdue
# Verify the legitimacy of the third paragraph
import jwt
salt = settings.SECRET_KEY
try:
# from token In order to get payload【 Don't verify validity 】
# unverified_payload = jwt.decode(token, None, False)
# print(unverified_payload)
# from token In order to get payload【 Verify legitimacy 】
payload = jwt.decode(jwt=token, key=salt, algorithms=["HS256"])
print(payload)
return (payload,token)
except jwt.exceptions.ExpiredSignatureError:
error = "token Has lapsed "
raise AuthenticationFailed({
"code": 401, "error": error})
except jwt.exceptions.DecodeError:
error = "token Authentication failed "
raise AuthenticationFailed({
"code": 401, "error": error})
except jwt.exceptions.InvalidTokenError:
error = " Illegal token"
raise AuthenticationFailed({
"code": 401, "error": error})
""" Three operations 1. Throw an exception , The follow-up is not implemented 2. return A tuple (1,2) Certification by , Called in the view request.user Is the first value of the tuple ; The other is request.auth 3.None """
- Create a new file to store Token Functional module of
# user/utils/jwt_create_token.py
import jwt
from django.conf import settings
def create_token(payload):
salt = settings.SECRET_KEY
# structure Header, The default is as follows
headers = {
'typ': 'jwt',
'alg': 'HS256'
}
jwt_token = jwt.encode(headers=headers, payload=payload, key=salt, algorithm='HS256')
return jwt_token
- Add global authentication
# settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['user.extensions.jwt_authenticate.JWTQueryParamsAuthentication',],
}
- modify views.py file
from rest_framework.views import APIView
from rest_framework.response import Response
from user.models import UserInfo
import datetime
from user.utils.jwt_create_token import create_token
from user.extensions.jwt_authenticate import JWTQueryParamsAuthentication
class LoginView(APIView):
""" The user login """
authentication_classes = [] # Cancel global authentication
def post(self,request,*args,**kwargs):
user = request.data.get('username')
pwd = request.data.get('password')
user_obj = UserInfo.objects.filter(username=user,password=pwd).first()
if not user_obj:
return Response({
'code':401,'error':' Wrong user name or password '})
payload = {
'user_id':user_obj.pk,# Custom user ID
'username':user_obj.username,# Custom user name
'exp':datetime.datetime.utcnow()+datetime.timedelta(minutes=1),# Set timeout ,1min
}
jwt_token = create_token(payload=payload)
return Response({
'code':200,'token':jwt_token})
# {"username":"admin","password":"admin123"}
class IndexView(APIView):
# Partial Certification
# authentication_classes = [JWTQueryParamsAuthentication,]
def get(self,request,*args,**kwargs):
return Response(" All right ")
3、 ... and 、DRF Use in djangorestframework-jwt
3.1 djangorestframework-jwt Usage flow
- install djangorestframework-jwt
pip install djangorestframework-jwt
- change settings Configuration file in
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES":(
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
# Global setting method , It can also be set in a single view , As previously written
)
}
# Set up JWT Parameters ( Such as expiration date ):
import datetime
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300), # Set up JWT Token Effective time of
'JWT_AUTH_HEADER_PREFIX': 'JWT', # Prefix set in the request header , Previously, it was done through the request body , There are differences
}
- Configure the routing
from rest_framework_jwt.views import obtain_jwt_token
# urlpatterns in
path('login/', obtain_jwt_token), # jwt Authentication interface ( The path can be named arbitrarily )
- Use with permission
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
'rest_framework_jwt.authentication.JSONWebTokenAuthentication', # Global setting method , It can also be set in a single view
],
'DEFAULT_PERMISSION_CLASSES': [
# IsAuthenticated Only authenticated users
'rest_framework.permissions.IsAuthenticated'
]
}


3.2 Use extension Django The user model in
- Reference address , Use exactly the same method
- Need to be in settings.py Named in the
AUTH_USER_MODDEL=" Application name . Class name "
3.3 Custom authentication successful return field
# user/utils/my_response_payload.py
def jwt_response_payload_handler(token, user=None, request=None):
""" Customize jwt Authentication successful return data """
return {
'token': token,
'user_id': user.id,
'username': user.username
}
# settings.py
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=60*5), # Set up JWT Token Effective time of
'JWT_AUTH_HEADER_PREFIX': 'JWT', # Set up Prefix in the request header
'JWT_RESPONSE_PAYLOAD_HANDLER':'user.utils.my_payload_response.jwt_response_payload_handler',
}
边栏推荐
- C语言指针(特别篇)
- Two schemes of unit test
- Selenium mouse sliding operation event
- Do you have any certificates with high gold content?
- Simulation volume leetcode [general] 1567 Length of the longest subarray whose product is a positive number
- Confitest of fixture py
- The essence of high availability
- Analysis of Hessian serialization principle
- Systick tick timer
- On December 8th, 2020, the memory of marketing MRC application suddenly increased, resulting in system oom
猜你喜欢

The essence of high availability

2022-06-30 Unity核心8——模型导入

STM32 serial port register library function configuration method

C语言指针(上篇)

数据在内存中的存储

MySql数据库-事务-学习笔记

Screen automatically generates database documents

LeetCode 715. Range module

Hard core sharing: a common toolkit for hardware engineers

Postman interface debugging method
随机推荐
Golang etcdv3 reports an error. The attribute in grpc does not exist
OpenGL frame buffer
Personal deduction topic classification record
STM32的时钟系统
徽商期货公司评级是多少?开户安全吗?我想开户,可以吗?
Analysis of Hessian serialization principle
2021 year end summary
Locust performance test 2 (interface request)
Leetcode刷题记录(数组)组合总和、组合总和 II
C语言指针(习题篇)
cmake命令行使用
C language pointer (special article)
外部中断实现按键实验
C language pointer (exercises)
个人力扣题目分类记录
Count the number of words in the string c language
MySql数据库-事务-学习笔记
Three updates to build applications for different types of devices | 2022 i/o key review
面试题:高速PCB一般布局、布线原则
How can I apply for a PMP certificate?