如何在django rest框架中更新Auth用户的密码
How to update password of Auth user in django rest framework
我是 django 休息框架的新手。我正在使用 reactJs 和 django 实现一个简单的登录、注册和忘记密码功能。所有功能都运行良好,但我面临的问题是,在注册时,数据库中的密码被加密然后保存在数据库中,但在更新密码时,新密码保存的与用户输入的密码完全相同。我希望它也像在注册时加密一样在数据库中加密。
我的serializer.py文件
from dataclasses import fields
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings
from django.contrib.auth.models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields='__all__'
# fields = ('username','first_name', 'last_name', 'email')
class UserSerializerWithToken(serializers.ModelSerializer):
token = serializers.SerializerMethodField()
password = serializers.CharField(write_only=True)
def get_token(self, obj):
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
payload = jwt_payload_handler(obj)
token = jwt_encode_handler(payload)
return token
def create(self, validated_data):
password = validated_data.pop('password', None)
instance = self.Meta.model(**validated_data)
if password is not None:
instance.set_password(password)
instance.save()
return instance
class Meta:
model = User
fields = ('token','first_name', 'last_name','email', 'username', 'password')
我的views.py文件
from asyncio.windows_events import NULL
from django.http import Http404, HttpResponseRedirect
from django.contrib.auth.models import User
from rest_framework import viewsets, permissions, status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.views import APIView
from .serializers import UserSerializer
from .serializers import UserSerializerWithToken
class UserViewSet(viewsets.ModelViewSet):
serializer_class = UserSerializer
queryset = User.objects.all()
@api_view(['GET'])
def current_user(request):
"""
Determine the current user by their token, and return their data
"""
serializer = UserSerializer(request.user)
return Response(serializer.data)
@api_view(['GET'])
def get_user(request):
"""
Filter the user wrt username and return the user data and token
"""
user=User.objects.filter(email=request.query_params['email'])
serializer = UserSerializer(instance=user, many=True)
if user.exists():
return Response(serializer.data)
else:
return Response(serializer.errors)
# ########################################################
# This is my update user api to update password
# it updates the password but not encrypting the password
# like signup encrypts in database
# ########################################################
@api_view(['PUT'])
def update_user(request,id):
user=User.objects.get(pk=id)
# userdata={'id':user.id,'username':user.username,'first_name':user.first_name,'last_name':user.last_name,'password':user.password}
serializer=UserSerializer(instance=user, data=request.data[0])
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors)
class UserList(APIView):
"""
Create a new user. It's called 'UserList' because normally we'd have a get
method here too, for retrieving a list of all User objects.
"""
# permission_classes = (permissions.AllowAny,)
def post(self, request, format=None):
serializer = UserSerializerWithToken(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# ############################################################################
# I tried the following way as well but it doesn't even update the password
# ############################################################################
#
# def put(self,request,id,format=None):
# user=User.objects.get(pk=id)
# serializer=UserSerializerWithToken(instance=user, data=request.data)
# if serializer.is_valid():
# serializer.save()
# return Response(serializer.data)
# else:
# return Response(serializer.errors)
这是我用于 api
的 url
path('users/<int:id>/',UserList.as_view()),
这就是我从 reactjs
中调用这个 api 的方式
function handleSubmit(e) {
let user=JSON.parse(localStorage.getItem('matched_user_token'))[0]
user.password=new_password
e.preventDefault()
if (ValidatePassword()) {
fetch('http://localhost:8000/core/users/'+user.id+'/', {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user)
})
.then(res => res.json())
.then(json => {
console.log("password changed successfully!"+json)
localStorage.setItem('changed',true)
navigate('/login')
}).catch(errors=>console.log(errors))
}
}
您需要像这样覆盖序列化程序的 update
方法:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields='__all__'
def update(self, instance, validated_data):
if 'password' in validated_data:
password = validated_data.pop('password', None)
instance.set_password(password)
return super().update(instance, validated_data)
我是 django 休息框架的新手。我正在使用 reactJs 和 django 实现一个简单的登录、注册和忘记密码功能。所有功能都运行良好,但我面临的问题是,在注册时,数据库中的密码被加密然后保存在数据库中,但在更新密码时,新密码保存的与用户输入的密码完全相同。我希望它也像在注册时加密一样在数据库中加密。
我的serializer.py文件
from dataclasses import fields
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings
from django.contrib.auth.models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields='__all__'
# fields = ('username','first_name', 'last_name', 'email')
class UserSerializerWithToken(serializers.ModelSerializer):
token = serializers.SerializerMethodField()
password = serializers.CharField(write_only=True)
def get_token(self, obj):
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
payload = jwt_payload_handler(obj)
token = jwt_encode_handler(payload)
return token
def create(self, validated_data):
password = validated_data.pop('password', None)
instance = self.Meta.model(**validated_data)
if password is not None:
instance.set_password(password)
instance.save()
return instance
class Meta:
model = User
fields = ('token','first_name', 'last_name','email', 'username', 'password')
我的views.py文件
from asyncio.windows_events import NULL
from django.http import Http404, HttpResponseRedirect
from django.contrib.auth.models import User
from rest_framework import viewsets, permissions, status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.views import APIView
from .serializers import UserSerializer
from .serializers import UserSerializerWithToken
class UserViewSet(viewsets.ModelViewSet):
serializer_class = UserSerializer
queryset = User.objects.all()
@api_view(['GET'])
def current_user(request):
"""
Determine the current user by their token, and return their data
"""
serializer = UserSerializer(request.user)
return Response(serializer.data)
@api_view(['GET'])
def get_user(request):
"""
Filter the user wrt username and return the user data and token
"""
user=User.objects.filter(email=request.query_params['email'])
serializer = UserSerializer(instance=user, many=True)
if user.exists():
return Response(serializer.data)
else:
return Response(serializer.errors)
# ########################################################
# This is my update user api to update password
# it updates the password but not encrypting the password
# like signup encrypts in database
# ########################################################
@api_view(['PUT'])
def update_user(request,id):
user=User.objects.get(pk=id)
# userdata={'id':user.id,'username':user.username,'first_name':user.first_name,'last_name':user.last_name,'password':user.password}
serializer=UserSerializer(instance=user, data=request.data[0])
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors)
class UserList(APIView):
"""
Create a new user. It's called 'UserList' because normally we'd have a get
method here too, for retrieving a list of all User objects.
"""
# permission_classes = (permissions.AllowAny,)
def post(self, request, format=None):
serializer = UserSerializerWithToken(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# ############################################################################
# I tried the following way as well but it doesn't even update the password
# ############################################################################
#
# def put(self,request,id,format=None):
# user=User.objects.get(pk=id)
# serializer=UserSerializerWithToken(instance=user, data=request.data)
# if serializer.is_valid():
# serializer.save()
# return Response(serializer.data)
# else:
# return Response(serializer.errors)
这是我用于 api
的 urlpath('users/<int:id>/',UserList.as_view()),
这就是我从 reactjs
中调用这个 api 的方式function handleSubmit(e) {
let user=JSON.parse(localStorage.getItem('matched_user_token'))[0]
user.password=new_password
e.preventDefault()
if (ValidatePassword()) {
fetch('http://localhost:8000/core/users/'+user.id+'/', {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user)
})
.then(res => res.json())
.then(json => {
console.log("password changed successfully!"+json)
localStorage.setItem('changed',true)
navigate('/login')
}).catch(errors=>console.log(errors))
}
}
您需要像这样覆盖序列化程序的 update
方法:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields='__all__'
def update(self, instance, validated_data):
if 'password' in validated_data:
password = validated_data.pop('password', None)
instance.set_password(password)
return super().update(instance, validated_data)