I am developing applications using Django REST Framework and Angular 4.
I do not know the treatment of token when UPDATE login user information.
我正在使用Django REST框架和角4开发应用程序。我不知道更新登录用户信息时如何处理令牌。
The user model of Django is customized as follows.
Login key is changed from username to email.
Django的用户模型定制如下。登录键从用户名更改为电子邮件。
[models.py]
(models.py)
class Account(AbstractBaseUser):
username = models.CharField(_('username'), max_length=30, unique=True)
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
email = models.EmailField(verbose_name='email address', max_length=255, unique=True)
profile = models.CharField(_('profile'), max_length=255, blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
objects = AccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
def user_has_perm(user, perm, obj):
return _user_has_perm(user, perm, obj)
def has_perm(self, perm, obj=None):
return _user_has_perm(self, perm, obj=obj)
def has_module_perms(self, app_label):
return self.is_admin
def get_short_name(self):
return self.first_name
@property
def is_superuser(self):
return self.is_admin
class Meta:
db_table = 'api_user'
swappable = 'AUTH_USER_MODEL'
The function to UPDATE user information from Angular 4 is implemented as follows.
New user information is put in Django REST Framework with function updateUserInfo.
从角4更新用户信息的功能实现如下。使用函数updateUserInfo将新的用户信息放入Django REST框架中。
[component.ts]
(component.ts)
updateUserInfo() {
this.authService.updateUserInfo({
email: this.editUserEmail,
username: this.editUserName,
profile: this.edtiUserProfile
})
.subscribe(
data => {
this.updateSuccessMessage = "success userinfo update";
this.updateErrorMessage = null;
this.authService.userInfo;
},
error => {
this.updateErrorMessage = "failed userinfo update";
this.updateSuccessMessage = null;
}
);
}
[service.ts]
(service.ts)
updateUserInfo(userUpdateInfo) {
return this.http
.put(this.UpdateUserUrl,
userUpdateInfo,
this.jwt()
);
}
jwt() {
if (this.LoginToken) {
let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization': 'JWT ' + this.LoginToken.token });
return new RequestOptions({ headers: headers });
}
}
The view and serializer for updating user information in Django are as follows.
用于在Django中更新用户信息的视图和序列化器如下所示。
[views.py]
(views.py)
class AuthInfoUpdateView(generics.UpdateAPIView):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = AccountSerializer
lookup_field = 'email'
queryset = Account.objects.all()
def get_object(self):
try:
instance = self.queryset.get(email=self.request.user)
return instance
except Account.DoesNotExist:
raise Http404
[serializers.py]
(serializers.py)
class AccountSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True, required=False)
class Meta:
model = Account
fields = ('id', 'username', 'email', 'profile', 'password')
def create(self, validated_data):
return Account.objects.create_user(request_data=validated_data)
def update(self, instance, validated_data):
if 'password' in validated_data:
instance.set_password(validated_data['password'])
else:
instance = super().update(instance, validated_data)
instance.save()
return instance
The problem that is happening now is the behavior when updating email.
Because USERNAME_FIELD is an email, updating the email has to update the token held by the front end.
But I do not know how to get token with new email.
现在正在发生的问题是更新电子邮件时的行为。因为USERNAME_FIELD是一个电子邮件,所以更新电子邮件必须更新前端持有的令牌。但是我不知道如何用新的电子邮件获得令牌。
1 个解决方案
#1
1
I think the only way to keep the user authenticated is to generate a new token and send it back, i don't know of another way to do this with django-rest-framework-jwt.
我认为保持用户认证的唯一方法是生成一个新的令牌并将其发送回去,我不知道用django-res -frame -jwt实现这一点的另一种方法。
For this to happen, you need to customize the put
method of your AuthInfoUpdateView
:
为此,您需要自定义AuthInfoUpdateView的put方法:
def put(self, request, *args, **kwargs):
serializer = self.serializer_class(self.get_object(), data=request.data, partial=True)
if serializer.is_valid():
instance = serializer.save()
# Generate a new token
payload = jwt_payload_handler(instance)
token = jwt.encode(payload, settings.SECRET_KEY)
response = JsonResponse({'token': token.decode('unicode_escape')})
response.status = 200
return response
else:
response = JsonResponse({'errors': serializer.errors})
response.status = 500
return response
As simple as this, you then just have to update the token on your front-end without prompting the user to login again.
简单地说,您只需更新前端的令牌,而无需提示用户再次登录。
Hope this helps!
希望这可以帮助!
#1
1
I think the only way to keep the user authenticated is to generate a new token and send it back, i don't know of another way to do this with django-rest-framework-jwt.
我认为保持用户认证的唯一方法是生成一个新的令牌并将其发送回去,我不知道用django-res -frame -jwt实现这一点的另一种方法。
For this to happen, you need to customize the put
method of your AuthInfoUpdateView
:
为此,您需要自定义AuthInfoUpdateView的put方法:
def put(self, request, *args, **kwargs):
serializer = self.serializer_class(self.get_object(), data=request.data, partial=True)
if serializer.is_valid():
instance = serializer.save()
# Generate a new token
payload = jwt_payload_handler(instance)
token = jwt.encode(payload, settings.SECRET_KEY)
response = JsonResponse({'token': token.decode('unicode_escape')})
response.status = 200
return response
else:
response = JsonResponse({'errors': serializer.errors})
response.status = 500
return response
As simple as this, you then just have to update the token on your front-end without prompting the user to login again.
简单地说,您只需更新前端的令牌,而无需提示用户再次登录。
Hope this helps!
希望这可以帮助!