Writing in the front
Log in to Django REST Framework JWT
The authentication mode of JWT mentioned above is very convenient to configure and implement. However, the company’s project login authentication is diverse, such as SSO, Oauth and other authentication methods of internal system;
Today we will talk about how to customize login authentication in the FRAMEWORK of DRF.
The code in this article is developed based on the Django REST Framework (3)
The text start
1. Prepare the SSO interface
New demo/mock_view.py This file is used to simulate the interface for SSO login and token authentication
- Login User password login is supported (for logical integrity only)
- Token verification does not implement specific logic but only demonstrates overall logic
Note: when setting a cookie, it will directly affect the default behavior of the browser. If the company expects a token to access all services, it must configure the top-level domain name. Similar to baidu.com rather than baike.baidu.com;
# 1. Add files
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.authentication import BaseAuthentication
from django.conf.urls import url
class AnyAuthentication(BaseAuthentication) :
def authenticate(self, request) :
return
@api_view(['POST'])
@authentication_classes((AnyAuthentication,))
@permission_classes((AllowAny, ))
def login(request) :
token = request.COOKIES.get('auth'."auth")
password = request.data.get('password'.' ')
username = request.data.get('username'.' ')
# user center check username password
response = Response({'user': "user_info".'token': token})
response.set_cookie('auth', token, domain="0.0.0.0", expires=30 * 24 * 60 * 60)
return response
@api_view(['GET'])
@authentication_classes((AnyAuthentication,))
@permission_classes((AllowAny,))
def check_token(request, token) :
token = request.COOKIES.get('auth')
# user center check token ...
data = {
"user_info": {
"username": "admin"."user_id": 1
},
"token": token
}
return Response(data)
mock_urls = [
url('^login/', login),
url(r"^check_token/(? P
[A-Za-z0-9]+)/$"
, check_token)
]
2.Urls.py new routefrom .mock_view import mock_urls
...
urlpatterns += mock_urls
Copy the code
2. Install dependencies
Services that mock remotely need to import a package of network requests
pipenv install requests
Copy the code
3. Implement logic
The utils/authentication.py file is added
Add utils/authentication.py
import requests
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication
from django.utils.translation import ugettext_lazy
from django.contrib.auth.models import User
class MyAuthentication(BaseAuthentication) :
def authenticate(self, request) :
token = request.COOKIES.get('auth')
if token is not None:
username = self.check_token(token)
if username is not None:
return User.objects.get(username=username), token
else:
raise exceptions.AuthenticationFailed(ugettext_lazy('Invalid token.'))
@staticmethod
def check_token(token) :
# Simulate request token validation
response = requests.get("http://localhost:8000/check_token/" + token)
if response.status_code == 200:
return response.json().get("user_info", {}).get("username")
2.Added authentication configuration in settings.py'DEFAULT_AUTHENTICATION_CLASSES': (
'utils.authentication.MyAuthentication'.'rest_framework_jwt.authentication.JSONWebTokenAuthentication'.'rest_framework.authentication.SessionAuthentication'.'rest_framework.authentication.BasicAuthentication',),Copy the code
4. Verify the results
The default BASCI authentication mode
$ curl -H 'Accept: application/json; indent=4'{-u admin: admin http://127.0.0.1:8000/api/article/1/"id": 1,
"creator": "admin"."tag": "Modern Poetry"."title": "如果"."content": "I'll never think of you again in this life, except in some night, when tears are wet with tears, if you will."
}
# Customize the token authentication mode
$ curl -H 'Accept: application/json; indent=4' --cookie "auth=123"{http://127.0.0.1:8000/api/article/1/"id": 1,
"creator": "admin"."tag": "Modern Poetry"."title": "如果"."content": "I'll never think of you again in this life, except in some night, when tears are wet with tears, if you will."
}
Copy the code
conclusion
Now that the logic for custom authentication is complete, some questions about authentication are summarized:
- What is the execution order of custom authentication and default authentication?
A: In the Settings file we configured the DEFAULT_AUTHENTICATION_CLASSES ancestor. The default execution sequence is top-down validation, and if both fail, a failed exception is thrown, which is eventually recovered by DRF and returned to the front end.
- What should I pay attention to when implementing MyAuthentication?
A: BaseAuthentication is the source code below, you can see that all DRF authentication needs to inherit BaseAuthentication and must be authenticate, it should be noted that the return value is a tuple (user, token); This, of course, is the underlying logic behind using Request. user in Django to get the current user.
class BaseAuthentication:
""" All authentication classes should extend BaseAuthentication. """
def authenticate(self, request) :
""" Authenticate the request and return a two-tuple of (user, token). """
raise NotImplementedError(".authenticate() must be overridden.")
def authenticate_header(self, request) :
""" Return a string to be used as the value of the `WWW-Authenticate` header in a `401 Unauthenticated` response, or `None` if the authentication scheme should return `403 Permission Denied` responses. """
pass
Copy the code
- So our system supports multiple authentication methods, no matter what kind of login can be quickly supported; Life is short. I use Python.
The following is a snippeof the Request class in Django to illustrate the order of execution and the retrieval of the User object
In the end, both the self-implemented authentication and DRF authentication inherit BaseAuthentication and authenticate; In fact, the source code is not difficult, but your heart.
The resources
- DRF certification