django使用总结——JWT认证

介绍

项目为前后端分离,采用JWT认证;业务需求采用自定义user
版本:
django-restframework-jwt: 1.11.*

settings.py配置

REST_FRAMEWORK = {
	'DEFFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
	'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_jwt.authentication.JSONWebTokenAuthentication',),
}

import datetime
JWT_AUTH = {
	# 配置jwt过期时间
	'JWT_EXPIRATION_DELTA': datetime.timedelta(hours=12)
	# 自定义返回内容,需要在user/utils/jwt_respone/目录下新建jwt_response_payload_handler.py
	'JWT_RESPONSE_PAYLOAD_HANDLER': 'user.utils.jwt_respone.jwt_response_payload_handler',
}

自定义User模型

django自带user模型不适合项目,所以自定义了
models.py

from django.db import models
from django.contrib.auth.hashers import check_password, make_password

class User(models.Model):
	real_name = models.CharField(verbose_name='姓名', max_length=64,)
	username = models.CharField(verbose_name='用户名', max_length=32, unique=True)
	password = models.CharField(verbose_name='密码', max_length=256)
	class Meta:
		verbose_name = '用户'
		verbose_name_plural = verbose_name
	# 加密密码
	def set_password(self, raw_password):
		self.password = make_password(raw_password)
		self._password = raw_password
	# 检验密码
	def check_password(self, raw_password):
		def setter(raw_password):
			self.set_passsword(raw_password)
			self._password = None
			self.save(update_fields=["password"])
		return check_password(raw_password, self.password, setter)
	
	@property
	def is_authenticated(self):
	 return True
	

创建认证链接(urls.py)

	from user.views.jwt_token import JWT
	urlpatterns = [
		path('jwt-token-auth/',JWT.as_view())
	]

自定义认证视图(JWT)

jwt_token.py

from rest_framework_jwt.views import JSONWebTokenAPIView
# 重写原序列化类
from user.serializers.jwt_token import JSONWebTokenSerializer

class JWT(JSONWebTokenAPIView):
	serializer_class = JSONWebTokenSerializer

重新认证序列化(JSONWebTokenSerializer)

这里主要重写了原JSONWebTokenSerializer类中的 authenticate函数(可以看下源码,很简单),我这里是直接替换自己的authenticate函数

from user.utils.username_auth_backend import authenticate

小技巧:
如果前端需要传入更多的信息,建议在JSONWebTokenSerializer中 init()函数下添加字段,validate()函数中同样添加

自定义authenticate函数

这里使用自定义User model验证

from user.models import User

def authenticate(username=None, password=None)try:
		user = User.objects.get(username=username)
		if user.check_password(password):
			return user
	except Exception as e:
		rasie e

自定义返回内容(jwt_response_payload_handler)

认证成功后返回内容(用户基本信息,权限等)

from user.models import User
def jwt_response_payload_handler(token,user=None,request=None):
	obj = User.objects.get(username=user)
	return {
		'token': token,
		'real_name': user.real_name,
		'status': 'ok',
	}

用户创建更新

from rest_framework import viewsets
from rest_framework.mixins import CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,ListModelMixin,GenericViewSet
from rest_framework import permissions
from user.utils.authentication import JSONWebTokenAuthentication
from user.serializers.user import UserSerializer
from user.models import User
class UserViewSet(CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,ListModelMixin,GenericViewSet)
 serializer_class = UserSerializer
 queryset = User.objects.all()
 authentication_class = (JSONWebTokenAuthentication,)
 def get_permissions(self):
 	"""
 	那些请求验证token
 	"""
 	if sel.action != 'create':
 		return [permissions.IsAuthenticated()]
 	else:
 		return []

创建User序列化

UserSerializer.py

from rest_framework import serializers
from rest_framework_jwt.settings import api_settings
from user.models import User

class UserSerializer(serializers.ModelSerializer):
	token = serializers.CharField(label='登录后TOKEN',read_only=True)
	password = serializers.CharField(label='密码',write_only=True)
	
	class Meta:
		model=User
		fields = ('id','username','token')
	def create(self,validated_data):
		user = super().create(validated_data)
		# 调用django的加密密码
		user.set_password(validated_data['password'])
		user.save()
		# 生成token
		jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
		jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
		payload = jwt_payload_handler(user)
		token = jwt_encode_handler(payload)
		user.token = token
		return user
	def update(self,instance,validated_data):
		serializers.raise_errors_on_nested_writes('update',self,validated_data)
		instance.set_password(validated_data['password'])
		instance.save()
		return instance

重写JSONWebTokenAuthentication

基本功能都和原生一样,由于JWT默认使用django 自带user模型,这里只需要修改user为自定义user.
authentication.py
1.重写了原来BaseJSONWebTokenAuthentication类中authenticate、authenticate_credentials函数中user
2.JSONWebTokenAuthentication类和原码功能一样,只是继承了新的BaseJSONWebTokenAuthentication类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值