- 导入模块
pip install djangorestframework-jwt
- 添加配置
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', ), } JWT_AUTH = { 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), }
- 注册完成后返回token
from rest_framework_jwt.settings import api_settings class CreateUserSerializer(serializers.ModelSerializer): """ 创建用户序列化器 """ ... token = serializers.CharField(label='登录状态token', read_only=True) # 增加token字段 class Meta: ... fields = ('id', 'username', 'password', 'password2', 'sms_code', 'mobile', 'allow', 'token') # 增加token ... def create(self, validated_data): """ 创建用户 """ # 移除数据库模型类中不存在的属性 del validated_data['password2'] del validated_data['sms_code'] del validated_data['allow'] 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
- Django REST framework JWT提供了登录签发JWT的视图,可以直接使用
from rest_framework_jwt.views import obtain_jwt_token urlpatterns = [ url(r'^authorizations/$', obtain_jwt_token), ]
- 向登陆返回字段中添加额外的字段(在users模块下添加新建utils.py)
def jwt_response_payload_handler(token, user=None, request=None): """ 自定义jwt认证成功返回数据 """ return { 'token': token, 'user_id': user.id, 'username': user.username }
- 添加配置文件使其调用自定义的返回字段
# JWT JWT_AUTH = { 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), 'JWT_RESPONSE_PAYLOAD_HANDLER': 'users.utils.jwt_response_payload_handler', }
- 重写登陆验证方法实现多账号登陆(修改Django认证系统的认证后端需要继承
django.contrib.auth.backends.ModelBackend
,并重写authenticate方法。)- 自定义登陆后端
def get_user_by_account(account): """ 根据帐号获取user对象 :param account: 账号,可以是用户名,也可以是手机号 :return: User对象 或者 None """ try: if re.match('^1[3-9]\d{9}$', account): # 帐号为手机号 user = User.objects.get(mobile=account) else: # 帐号为用户名 user = User.objects.get(username=account) except User.DoesNotExist: user = None finally: return user class UsernameMobileAuthBackend(ModelBackend): """ 自定义用户名或手机号认证 """ def authenticate(self, request, username=None, password=None, **kwargs): user = get_user_by_account(username) if user is not None and user.check_password(password): return user
- 在配置文件中使用自定义的登陆
# 修改默认的认证后端 AUTHENTICATION_BACKENDS = [ 'users.utils.UsernameMobileAuthBackend', ]
- 自定义登陆后端