官方文档
pip install djangorestframework-simplejwt
django-setting 中配置 simplejwt 参数
# 在setting中配置认证插件
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
# 注册应用
INSTALLED_APPS=[
'rest_framework_simplejwt',
]
#在 setting 配置认证插件的参数
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_code',
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'AUTH_HEADER_TYPES': ('Token',),
}
SIMPLE_JWT 配置说明
一些 Simple JWT 的行为可以通过以下中的设置变量进行自定义
官方文档
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': False,
'UPDATE_LAST_LOGIN': False,
'ALGORITHM': 'HS256',
'SIGNING_KEY': settings.SECRET_KEY,
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'JWK_URL': None,
'LEEWAY': 0,
'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}
1、在用户应用下新建:utlis.py(auth_user.utlis.CustomBackend)
from .models import UserProfile
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
class CustomBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
# noinspection PyBroadException
try:
# 添加了一个手机验证,如果需要其他验证再加
user = UserProfile.objects.get(Q(username=username) | Q(mobile=username))
if user.check_password(password):
return user
except Exception as e:
return None
2、setting中设置:AUTHENTICATION_BACKENDS
# 自定义认证后端
AUTHENTICATION_BACKENDS = ('auth_user.utlis.CustomBackend',)
1、在用户应用下新建视图:MyTokenObtainPairView,重写sm-jwt的响应方式
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
class FormulaTokenObtainPairSerializer(TokenObtainPairSerializer):
def create(self, validated_data):
pass
def update(self, instance, validated_data):
pass
def validate(self, attrs):
data = super().validate(attrs)
refresh = self.get_token(self.user)
data['username'] = self.user.username
data['mobile'] = self.user.mobile
data['refresh'] = str(refresh)
data['access'] = str(refresh.access_token)
return {"code": "200", "msg": "ok", "data": data}
class FormulaTokenObtainPairView(TokenObtainPairView):
serializer_class = FormulaTokenObtainPairSerializer
2、添加到视图url
from .authorization import FormulaTokenObtainPairView
urlpatterns = [
path("login", FormulaTokenObtainPairView.as_view(), name="login"), # 获取token
]
3、在工程urls添加路由
urlpatterns = [
# path('token', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('token/refresh', TokenRefreshView.as_view(), name='token_refresh'),
path('token/verify', TokenVerifyView.as_view(), name='token_verify'),
path('auth/', include("auth_user.urls")), # 重写token
]
4、作为登录鉴权,获取token
1、在新建文件:formula -> middleware.py 中间件
# 登录过期时 自定义 返回
class ExceptionChange:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
def process_template_response(self, request, response):
if hasattr(response, 'data'):
data = response.data
if isinstance(data, dict) is True:
if "detail" in data.keys():
# 用户名或密码错误
if data.get("detail") == "找不到指定凭据对应的有效用户":
del response.data["detail"]
response.data["code"] = 402
response.data["msg"] = "用户名或者密码错误!"
# 验证信息过期 token 过期
if data.get("detail") == "此令牌对任何类型的令牌无效":
del response.data["detail"]
del response.data["messages"]
response.data["code"] = 401
response.data["msg"] = "登录已过期,请重新登录"
# 未使用验证信息 未带验证信息请求
if data.get("detail") == "身份认证信息未提供。": # 身份认证信息未提供。
del response.data["detail"]
response.data["code"] = 401
response.data["msg"] = "登录已过期,请重新登录"
# refresh 无效或者过期
if data.get("detail") == "令牌无效或已过期": # 身份认证信息未提供。
del response.data["detail"]
response.data["code"] = 403
response.data["msg"] = "令牌无效或已过期"
return response
2、在setting中配置
MIDDLEWARE = [
...
# 自定义:错误状态返回
"formula.middleware.ExceptionChange",
]
1、 新建文件:File : formula -> mixin.py
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
class FormulaApiViews(APIView):
permission_classes = (IsAuthenticated,)
2、在之后的每个视图继承此方法,用于鉴权;可扩展
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "000000"}' \
http://localhost:8000/api/v1/login
{
"access":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU",
"refresh":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImNvbGRfc3R1ZmYiOiLimIMiLCJleHAiOjIzNDU2NywianRpIjoiZGUxMmY0ZTY3MDY4NDI3ODg5ZjE1YWMyNzcwZGEwNTEifQ.aEoAYkSJjoWH1boshQAaTkf8G3yn0kapko6HFRt7Rh4"
}
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"refresh":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImNvbGRfc3R1ZmYiOiLimIMiLCJleHAiOjIzNDU2NywianRpIjoiZGUxMmY0ZTY3MDY4NDI3ODg5ZjE1YWMyNzcwZGEwNTEifQ.aEoAYkSJjoWH1boshQAaTkf8G3yn0kapko6HFRt7Rh4"}' \
http://localhost:8000/api/v1/token/refresh
{
"access":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU",
}
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"access":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU"}' \
http://localhost:8000/api/v1/token/verify
{}