0

Given I have this create user view

class UserView(View): def post(self, request): try: data = json.loads(request.body) encrypted_username_hex = data.get('username', None) encrypted_password_hex = data.get('password', None) phone_number = data.get('phone_number', None) email = data.get('email', None) missing_fields = [field for field in ['username', 'password', 'email'] if data.get(field) is None] if missing_fields: return JsonResponse({"error": f"Missing required field(s): {', '.join(missing_fields)}"}, status=400) session_id = request.session.session_key print("user create ses", session_id) private_key_pem, _ = RSAKeyManager.get_keys(session_id) if not private_key_pem: return JsonResponse({"error": "Invalid session or RSA keys not found"}, status=404) print("private key", private_key_pem) username = RSAHandler.decrypt_from_hex(private_key_pem, encrypted_username_hex) password = RSAHandler.decrypt_from_hex(private_key_pem, encrypted_password_hex) user = CustomUser.objects.create_user(username=username, email=email, password=password, phone_number=phone_number) return JsonResponse({"user": user.email, "phone_number": user.phone_number}, status=201) except IntegrityError as e: if 'username' in str(e): return JsonResponse({"error": "This username is already taken."}, status=400) elif 'email' in str(e): return JsonResponse({"error": "This email is already in use."}, status=400) else: return JsonResponse({"error": "There was an error with your request."}, status=400) except ValidationError as e: return JsonResponse({"error": str(e.messages[0])}, status=400) except Exception as e: traceback.print_exc() return JsonResponse({"error": "Internal server error."}, status=500) 

And this custom user model:

class CustomUserManager(BaseUserManager): def create_user(self, username, email, password=None, phone_number=None, **extra_fields): if not email: raise ValueError(_('The Email must be set')) email = self.normalize_email(email) user = self.model(username=username, email=email, phone_number=phone_number, **extra_fields) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, username, email, password=None, phone_number=None, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) if extra_fields.get('is_staff') is not True: raise ValueError(_('Superuser must have is_staff=True.')) if extra_fields.get('is_superuser') is not True: raise ValueError(_('Superuser must have is_superuser=True.')) return self.create_user(username, email, password, phone_number, **extra_fields) class CustomUser(AbstractBaseUser, PermissionsMixin): username = models.CharField(max_length=150, unique=True) email = models.EmailField(unique=True) phone_number = models.CharField(max_length=15, blank=True, null=True) is_staff = models.BooleanField(default=False) is_active = models.BooleanField(default=True) banned = models.BooleanField(default=False) created_at = models.DateTimeField(default=timezone.now) updated_at = models.DateTimeField(auto_now=True) USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['username', "password"] objects = CustomUserManager() # Add related_name to groups and user_permissions fields groups = models.ManyToManyField( 'auth.Group', verbose_name=_('groups'), blank=True, help_text=_('The groups this user belongs to. A user will get all permissions granted to each of their groups.'), related_name="custom_user_set", # Changed related_name related_query_name="user", ) user_permissions = models.ManyToManyField( 'auth.Permission', verbose_name=_('user permissions'), blank=True, help_text=_('Specific permissions for this user.'), related_name="custom_user_set", # Changed related_name related_query_name="user", ) def __str__(self): return self.username 

And this login view:

 class LoginView(View): def post(self, request): try: data = json.loads(request.body) email = data.get('email', None) encrypted_password_hex = data.get('password', None) session_id = request.session.session_key private_key_pem, _ = RSAKeyManager.get_keys(session_id) print(session_id) password = RSAHandler.decrypt_from_hex(private_key_pem, encrypted_password_hex) print(email) print(password) # Authenticating the user user = authenticate(username=email, password=password) user = authenticate(username='[email protected]', password='test') print("user", user) if user is not None: # User is authenticated, now generate a JWT token payload = { 'session_id': request.session.session_key, 'username': user.username, } jwt_token = jwt.encode(payload, settings.SECRET_KEY, algorithm='HS256') return JsonResponse({"token": jwt_token, "user": user.username}, status=200) else: # Authentication failed return JsonResponse({"error": "Invalid credentials"}, status=401) except Exception as e: return JsonResponse({"error": str(e)}, status=500) 

I cannot manage to auth,

I tried manually to specify user/pass but still, user is always none:

user = authenticate(username='[email protected]', password='test') 

The user exists in the db, the password is corretly hashed it seems, the password is the same (in plain text) not sure what I m doing wrong at this point :(

Flow is as such ->

  1. Client requests RSA pub key and ses id
  2. Client sends user/create data as: encrypted password, pain text email and other fields, backend stores email and plain text hashed password(rsa decrypted) using django set_password
  3. Client requests user/login with email and rsa_encrypted_password, backend decrypts password to plain text, and calls django authenticate with plain text email/password)

Even with hardcoded data, auth still fails:

 def get(self, request): try: random_string = str(uuid.uuid4())[:4] from django.contrib.auth import authenticate CustomUser.objects.create_user(username=random_string, email=random_string, password='test', phone_number='test') user = authenticate(request, email=random_string, password='test') print(user) return JsonResponse({"user": user}) except Exception as e: return JsonResponse({'er': str(e)}) 

For this line i use username instead of email aswell user = authenticate(request, username=random_string, password='test'), same outcome, returns None

Manually checking user password (for hardcoded example, works)

 user = CustomUser.objects.get(username=random_string) print("check pass", check_password('test', user.password)) 

check_password, returns True

15
  • Since you perform hashing manually first (i.e. password = RSAHandler.decrypt_from_hex(private_key_pem, encrypted_password_hex), you will need to do that too for the **username/email as well. Commented Mar 4, 2024 at 8:50
  • Well I send password rsa encrypted but email is in plain text, I pass plain text emai/password to django authenticate method Did I somehow missed something with the user mode customization? Commented Mar 4, 2024 at 8:54
  • so when creating you send the username encrypted, when you login, you don't? Commented Mar 4, 2024 at 8:55
  • 1
    Why are you encrypting when sending the username / password anyway? Can't you leave that upto the TLS setup of your website? Commented Mar 4, 2024 at 9:29
  • 1
    What is the value of your AUTHENTICATION_BACKENDS setting? Commented Mar 4, 2024 at 9:55

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.