如何使用Django REST Framework UPDATE USERNAME_FIELD处理令牌

时间:2017-06-29 08:36:45

标签: python angularjs django django-rest-framework django-rest-framework-jwt

我正在使用Django REST Framework和Angular 4开发应用程序 UPDATE登录用户信息时,我不知道令牌的处理方式

Django的用户模型定制如下 登录密钥已从用户名更改为电子邮件

[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'

从Angular 4更新用户信息的功能如下实现 新的用户信息放在具有函数updateUserInfo的Django REST Framework中

[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]

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 });
  }
}

用于在Django中更新用户信息的视图和序列化程序如下所示。

[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]

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

现在发生的问题是更新电子邮件时的行为 由于USERNAME_FIELD是电子邮件,因此更新电子邮件必须更新前端持有的令牌 但我不知道如何使用新邮件获取令牌。

1 个答案:

答案 0 :(得分:2)

我认为保持用户身份验证的唯一方法是生成一个新令牌并将其发回,我不知道用django-rest-framework-jwt执行此操作的另一种方法。

为此,您需要自定义put的{​​{1}}方法:

AuthInfoUpdateView

就这么简单,您只需更新前端的令牌而不提示用户再次登录。

希望这有帮助!