Django注册成功后无法登录,提示用户名或密码错误
新用户注册后登录提示用户名或密码错误问题排查与修复
问题描述
新用户注册成功后,登录时始终提示「用户名或密码错误」,确认输入无拼写错误,怀疑问题出在密码的哈希编码环节。相关代码如下:
注册代码
@csrf_exempt def api_register(request): data = json.loads(request.body) username = data['username'] password_1 = data['password_1'] password_2 = data['password_2'] # 1,check if two pw is same if password_1 != password_2: return JsonResponse({"code": 0, "msg": "pw not consistant"}) else: m = hashlib.md5() m.update(password_1.encode()) password_m = m.hexdigest() # 2 check if username exists users = User.objects.filter(username=username) if users: return JsonResponse({"error": "username already exists"}) else: try: user = User.objects.create_user(username = username, password = password_m) user.set_password(password_m) user.save() user.is_active = True user.success = True ret_data = {"username": user.username, 'uid': user.id, 'password': user.password} token = TimestampSigner(sep='.').sign_object(ret_data) ret_data['token'] = token ret = {"code": 1, "msg": ret_data} except Exception as e: print('--create user error is %s' % e) return JsonResponse({"error": "username already exists"}) return JsonResponse(ret)
登录代码
@csrf_exempt def api_login(request): data = json.loads(request.body) user = authenticate(**data) #same as authenticate(username=data['username'],password=data['password'] if user: ret_data = {"username":user.username,'uid':user.id} token = TimestampSigner(sep='.').sign_object(ret_data) ret_data['token'] = token ret = {"code":1,"msg":ret_data} print("ret ", ret) else: ret = {"code":0,"msg":"username or password wrong!" } return JsonResponse(ret)
问题根源
重复哈希导致密码不匹配:
- 代码先对原始密码做MD5哈希得到
password_m,调用create_user时,Django内置方法会自动对传入的password参数做哈希处理; - 随后又调用
user.set_password(password_m),把已经MD5哈希过的字符串再次用Django的密码哈希算法处理一遍; - 最终数据库存储的是「MD5哈希值的Django哈希值」,而登录时
authenticate仅对用户输入的原始密码做一次Django哈希,两者无法匹配。
- 代码先对原始密码做MD5哈希得到
冗余操作:
create_user方法默认会将is_active设为True,无需额外设置;且调用create_user后不需要再手动调用save()。
修复后的注册代码
@csrf_exempt def api_register(request): data = json.loads(request.body) username = data['username'] password_1 = data['password_1'] password_2 = data['password_2'] # 检查两次输入的密码是否一致 if password_1 != password_2: return JsonResponse({"code": 0, "msg": "两次输入的密码不一致"}) # 检查用户名是否已存在 if User.objects.filter(username=username).exists(): return JsonResponse({"error": "用户名已存在"}) try: # create_user会自动处理密码哈希存储,直接传入原始密码即可 user = User.objects.create_user(username=username, password=password_1) ret_data = {"username": user.username, 'uid': user.id} token = TimestampSigner(sep='.').sign_object(ret_data) ret_data['token'] = token ret = {"code": 1, "msg": ret_data} except Exception as e: print(f'创建用户错误:{e}') return JsonResponse({"error": "创建用户失败"}) return JsonResponse(ret)
修复说明
- 移除手动MD5哈希步骤,直接将原始密码传给
create_user,Django会自动使用安全的内置哈希算法(默认PBKDF2)处理密码,保证登录验证匹配; - 删除重复的
set_password和多余的save()操作,简化逻辑; - 调整提示信息为中文表述,更符合使用习惯。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

