Django rest framework | Knox authentication password not hashed in database - python

I have created serializer for registering users in Django with djangorestframework. I am also using django-rest-knox for token authentication. Problem is that passwords are not hashed in database when creating users. Below is the code of serializer:
class RegisterSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email', 'password')
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
# user = User.objects.create_user(
# validated_data['username'], validated_data['email'], validated_data['password'])
user = User(
username=validated_data['username'], email=validated_data['email'])
user.set_password(validated_data['password'])
user.save()
return user
Please note that I have tried both commented and uncommented methods of creating user in the above code. In both cases, passwords are saved as raw in database. Below is the part of settings.py related to implementing knox token authentication:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ('knox.auth.TokenAuthentication',)
}
Any suggestions why password are not hashed?

Related

Create super user working, create normal user not (Django)

Made a custom user model, a serializer for each users data and a manager. When imported breakpoint while making a superuser function was executed and password that i gave the superuser was hashed and added in the database. When i tried adding a normal user in database function was not executed and django was not using my UserProfileManager at all. Normal user was created but not using my Model or Manager
serializers.py
class UserProfileSerializer(serializers.ModelSerializer):
"""Serializes a user profile object"""
class Meta:
model = models.UserProfile
fields = ('id', 'email', 'name', 'password')
extra_kwargs = {
'password':{
'write_only': True,
'style':{'input_type':'password'}
}
}
def create(self, validated_data):
"""Create and return a new user"""
user = models.UserProfile.objects.create(
email=validated_data['email'],
name=validated_data['name'],
password=validated_data['password']
)
return user

Registered User can't login with credentials django rest framework

The issue i've got is my login endpoint wont permit me to login with authenticated users for unkown reasons
Here is my serializers.py file
class UserSerializer(ModelSerializer):
class Meta:
model = User
fields = ['id','first_name','last_name','email','is_seller','date_joined']
extra_kwargs ={
'password':{'write_only':True}
}
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
Here is my views.py for Login
class LoginAPIView(APIView):
def post(self, request):
email = request.data['email']
password = request.data['password']
print(email)
print(password)
# since email is unique use first()
user = User.objects.filter(email=email).first()
print(user)
if user is None:
raise exceptions.AuthenticationFailed(f'User {email} not found')
if not user.check_password(password):
raise exceptions.AuthenticationFailed(f'Incorrect Password')
return Response(UserSerializer(user).data)
Now when i do try to login the and given user i get this error below from post man
{
"detail": "Incorrect Password"
}
And these are my logs below
Forbidden: /api/sellers/login/
[15/Jul/2021 21:50:30] "POST /api/sellers/login/ HTTP/1.1" 403 31
I've been unable for hours to figure out why exactly register users can't sign in and also i am using a Custom user model and in my settings.py file the Rest_Framework is set to AllowAny...Thanks in advance for any help...
As Tim Roberts suggested, make sure your fields includes password. Your extra_kwargs for password still requires that password is either a field on the model (in the fields list) or defined as a type of field directly on the Serializer.
class UserSerializer(ModelSerializer):
class Meta:
model = User
fields = [
'id',
'first_name',
'last_name',
'email',
'is_seller',
'date_joined',
'password', # <- note added field
]
extra_kwargs = {
'password': {'write_only':True}
}

Django : Can I use CreateView to create a User object where User is just Django's built in User model?

I am trying to create a simple user login system where a user gets to sign up on one page and then use those credentials to login to the website on another page. Here's my sign-up and login views:
class SignupView(CreateView):
model = User
form_class = SignupForm
template_name = 'journal_app/signup.html'
success_url = reverse_lazy('home')
class LoginUserView(LoginView):
template_name = 'journal_app/login.html'
As you can see I'm using the CreateView to create User objects. After the user signs up I can see that the record is successfully updated in the Users group in my Admin console. The problem is that when I try to login, it always throws me a username/password don't match error. Any ideas what could be the reason? I am a beginner at Django so it could be something pretty simple.
SignupForm-
class SignupForm(forms.ModelForm):
class Meta:
model = User
fields = ['first_name', 'username', 'password']
widgets = {
'password': forms.PasswordInput()
}
The problem is that you need to hash the password. Django stores a hash of the password [Django-doc]. If you make a custom user model, you should normally implement a UserManager [Django-doc] as well. This takes a password, and will hash it, for examply by calling a method .set_password(…) [Django-doc]. This method will then hash the password.
You thus can rewrite the form to save the user with:
class SignupForm(forms.ModelForm):
class Meta:
model = User
fields = ['first_name', 'username', 'password']
widgets = {
'password': forms.PasswordInput()
}
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data['password'])
if commit:
user.save()
return user

DRF how to make register api view only available for my react app

So I can't figure out how to make this registration view can only accept registrations from my react app. Currently, anybody can put values in my fields and then my API will accept it. I would like to make it restricted in some way so that it only accepts values through the apps that I allow.
serializers.py
# Serializer for user info for the registration API
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User # for the User model, use get_user_model for custom
fields = ('id', 'username', 'password', 'email', 'first_name', 'last_name',)
extra_kwargs = {'password': {'write_only': True}}
read_only_fields = ('id',)
# override create method
def create(self, validated_data):
user = User.objects.create(
username=validated_data['username'],
email=validated_data['email'],
first_name=validated_data['first_name'],
last_name=validated_data['last_name']
)
user.set_password(validated_data['password'])
user.save()
return user
views.py
class RegisterUserView(generics.CreateAPIView):
model = User
permission_classes = [permissions.AllowAny, ]
serializer_class = UserSerializer
queryset = ''

Django Rest not creating extended UserProfile

I'm using Django Rest Framework and I've created an extended UserProfile model as follows:
class UserProfile(models.Model):
user = models.OneToOneField(User)
#Some Fields for UserProfile
def user_profile_url(self):
return reverse('user_profile', args=(self.user.id, "{}-{}".format(self.user.first_name, self.user.last_name)))
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
However, on signing up using rest_auth's /registration endpoint: http://django-rest-auth.readthedocs.org/en/latest/api_endpoints.html#registration, the UserProfile is not being created even though the User is created. In my serializers.py, I've done the following for users who sign up
class UserSignUpSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email',)
def create(self, validated_data):
user = User(email=validated_data['email'], username=validated_data['email'])
user.set_password(validated_data['password'])
user.save()
profile = UserProfile(user=user)
profile.save()
return user
Where am I going wrong?
Because request goes here https://github.com/Tivix/django-rest-auth/blob/master/rest_auth/registration/views.py#L38 and doesn't call serializer.create() actually.
Try to override signup form as suggested in the docs:
ACCOUNT_FORMS = {
'signup': 'path.to.custom.SignupForm'
}
example of the profile form:
https://djangosnippets.org/snippets/2081/

Categories

Resources