我使用all-auth / django-rest-auth进行授权。当用户更改他/她的用户名时,Django(Django REST框架)会更改用户的令牌,这会使用户从应用程序注销;如果用户的令牌无效,我会将应用设置为退出。
我想要做的是即使用户更改User
中的用户名,电子邮件或任何字段,它也会保留令牌。
这是settings.py
REST_USE_JWT = True
AUTHENTICATION_BACKENDS = (
# Needed to login by username in Django admin, regardless of `allauth`
'django.contrib.auth.backends.ModelBackend',
# `allauth` specific authentication methods, such as login by e-mail
'allauth.account.auth_backends.AuthenticationBackend',
# Facebook OAuth2
'social_core.backends.facebook.FacebookAppOAuth2',
'social_core.backends.facebook.FacebookOAuth2',
# django-rest-framework-social-oauth2
'rest_framework_social_oauth2.backends.DjangoOAuth2',
)
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=30),
}
...
谢谢!
答案 0 :(得分:1)
建议:
1)将用户名设置为某个哈希对象(uuid)并创建名为 username_custom 的新字段, (更改您的登录和注册视图)
2)准备你的模式:
USERNAME_FIELD = 'username'
所以它是Django中的默认用户名
3)永远不要更新默认字段用户名,您的令牌永远不会更改。
1)使用包用于用户模型:https://github.com/jcugat/django-custom-user
2)模型示例
class UserModel(AbstractEmailUser):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
username = models.CharField(max_length=255, db_index=True, unique=True)
email = models.EmailField(unique=False, db_index=True)
username_custom = models.CharField(max_length=255, db_index=True, unique=True)
USERNAME_FIELD = 'username'
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
self.first_name = self.first_name.capitalize()
self.last_name = self.last_name.capitalize()
self.full_name = '{} {}'.format(self.first_name.capitalize(), self.last_name.capitalize())
super(UserModel, self).save(force_insert, force_update)
def clean(self):
if UserModel.objects.filter(email=self.email, username_custom=self.username_custom).exists():
raise ValidationError('User already exists!')
您可以看到有新字段 username_custom 。
现在休息api创建用户。
class UserRegister(APIView):
permission_classes = (AllowAny,)
authentication_classes = ()
def post(self, request):
data = request.data
# or you can check username_custom
if UserModel.objects.filter(email=data['email']).exists():
return Response(data={'success': False, 'msg': 'User with email already exists.'},
status=status.HTTP_403_FORBIDDEN)
data['username'] = '%s' % uuid.uuid4()
serializer = UserRegisterSerializer(data=data)
if serializer.is_valid(raise_exception=True):
serializer.save()
token_data = UserModel.objects.get(email=serializer.data['email'])
payload = jwt_payload_handler(token_data)
token = jwt_encode_handler(payload)
return Response(data={'success': True, 'user': serializer.data,
'token': token_prefix + token}, status=status.HTTP_201_CREATED)
return Response(data={'success': False, 'msg': serializer.errors},
status=status.HTTP_400_BAD_REQUEST)
class UserRegisterSerializer(serializers.ModelSerializer):
username = serializers.UUIDField()
class Meta:
model = UserModel
fields = ('password', 'email', 'user_type', 'username', 'first_name', 'last_name', 'username_custom',)
def create(self, validated_data):
user = UserModel.objects.create_user(**validated_data)
return user
您必须预先制作UPDATE方法以检查唯一的电子邮件字段,这样您就不会在您的数据库中收到2封电子邮件,也不会在您想要授权的情况下收到username_custom。
class UserLoginView(APIView):
permission_classes = (AllowAny,)
def get(self, request, email, password):
# or you can check username_custom
if not UserModel.objects.filter(email=email.lower()).exists():
return Response(data={'success': False, 'msg': 'Email or password wrong!'},
status=status.HTTP_404_NOT_FOUND)
qv = UserModel.objects.get(email=email.lower())
user = authenticate(username=qv.username, password=password)
if user:
if user.is_active:
token_data = UserModel.objects.get(id=user.id)
payload = jwt_payload_handler(token_data)
token = jwt_encode_handler(payload)
return Response(data={'success': True,
'token': token_prefix + token}, status=status.HTTP_200_OK)
return Response(data={'success': False, 'msg': 'Email or password wrong!'},
status=status.HTTP_400_BAD_REQUEST)