diff --git a/accounts/user_login_backend.py b/accounts/user_login_backend.py index 73cdca1b..7b6a58ca 100644 --- a/accounts/user_login_backend.py +++ b/accounts/user_login_backend.py @@ -2,25 +2,54 @@ from django.contrib.auth import get_user_model from django.contrib.auth.backends import ModelBackend +# 模块级注释——accounts应用的自定义认证后端文件, +# 继承Django内置ModelBackend,扩展支持"用户名或邮箱"双登录方式, +# 适配项目中用户可能使用邮箱作为登录凭证的业务需求,保持与Django认证系统的兼容性 class EmailOrUsernameModelBackend(ModelBackend): """ - 允许使用用户名或邮箱登录 + 自定义用户认证后端,继承Django内置ModelBackend + 核心功能:允许用户使用「用户名」或「邮箱」两种方式登录, + 兼容Django默认认证流程,不破坏原有用户模型和权限体系 """ def authenticate(self, request, username=None, password=None, **kwargs): + """ + 重写认证核心方法,实现用户名/邮箱双登录逻辑 + :param request: HTTP请求对象(用于传递请求上下文,本方法未直接使用) + :param username: 登录输入的标识(可能是用户名或邮箱) + :param password: 登录输入的密码(明文,需通过check_password验证) + :param kwargs: 额外关键字参数(兼容Django认证系统的扩展需求) + :return: 认证成功返回BlogUser对象,失败返回None + """ + # 判断输入的标识是否包含@符号:含@则视为邮箱登录,否则视为用户名登录 if '@' in username: - kwargs = {'email': username} + kwargs = {'email': username} # 构造邮箱查询条件 else: - kwargs = {'username': username} + kwargs = {'username': username} # 构造用户名查询条件 + try: + # 根据查询条件(用户名/邮箱)从数据库获取用户对象 + # get_user_model():动态获取当前项目激活的用户模型(此处为accounts.BlogUser) user = get_user_model().objects.get(**kwargs) + + # 验证输入的密码是否正确(check_password会自动比对明文与数据库中哈希后的密码) if user.check_password(password): - return user + return user # 密码验证通过,返回用户对象(认证成功) + + # 捕获用户不存在的异常(查询不到时触发) except get_user_model().DoesNotExist: - return None + return None # 用户不存在,返回None(认证失败) def get_user(self, username): + """ + 重写用户获取方法,根据用户主键(pk)查询用户对象 + 是Django认证后端必须实现的方法,用于认证成功后获取完整用户信息 + :param username: 实际为用户的主键ID(Django认证系统默认传递pk作为参数) + :return: 查询成功返回BlogUser对象,失败返回None + """ try: + # 根据主键ID查询用户(get_user_model()确保兼容自定义用户模型) return get_user_model().objects.get(pk=username) + # 捕获用户不存在的异常 except get_user_model().DoesNotExist: - return None + return None # 用户不存在,返回None \ No newline at end of file