Django authenticate() 函数查找不到与提交的用户名和密码匹配的用户,则会返回 None。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django authenticate() 函数查找不到与提交的用户名和密码匹配的用户,则会返回 None。相关的知识,希望对你有一定的参考价值。
在你的user APP下面添加一个utils.py文件
class UsernameMobileBackend(ModelBackend): def authenticate(self, request, username=None, password=None, **kwargs): """ 重写人做方法 """ #使用账号查询运河 #如果用户名查询到用户,就校验密码 #密码校验成功就返回user user = get_user_by_account(username) if user and user.check_password(password): return user else: return None
然后在你的配置文件里面添加
AUTHENTICATION_BACKENDS = [\'users.utils.UsernameMobileBackend\']
就可以解决了.
如果不可以就:
-
检查您的用户名和密码是否正确,并确保它们与数据库中的数据一致。
-
确保您正在使用正确的身份验证后端。如果您使用的是 Django 默认的身份验证后端,可以在
AUTHENTICATION_BACKENDS
设置中检查配置。 -
确认您的数据库中存在用户数据。可以使用 Django shell 进行验证。
-
确认您的
User
模型继承自 Django 的AbstractBaseUser
或AbstractUser
。如果您的User
模型未正确配置,则可能导致身份验证失败。
如果以上步骤都没有解决您的问题,您可以检查 Django 日志文件以查看是否有任何报错信息。另外,也可以尝试在 Django shell 中手动验证用户信息,以检查是否存在任何问题。
django authenticate
程序少不了验证用户与权限分配。通过 Django 自带以及我们一些扩展就能够满足验证与权限的需求。
我在使用 Django 遇到的“login(request, user) 之后,再重定向这个 request,然后 request.user 变成了 anonymous user”问题。
使用了一个自定义的 backend,然后使用 authenticate(parm) 能够获取到 user。
搜索了这些
django login in and redirect to current_url - Google 搜索
django 登陆之后丢失信息 - Google 搜索
Redirect to the originally requested page after django registration and email activation | Mitch Fournier
Django:Redirect after login success - Stack Overflow
django redirect after login in without user - Google 搜索
django redirect after login not working - Google 搜索django last login session - Google 搜索
找了几小时都没有找到答案,一直尝试 login(request, user),每次 login 成功了,回来又是 request user。我大部分时间怀疑 login() 方法是不是有问题,但并没有什么收获。然后看了看自定义的 backend,没发现问题,并且通过 authenticate 能够拿到 user。然后问了同事,他们也找到问题。
问了别人都没解决,那只能再次自己动手了。这次我想从底层弄起,想 http 是无状态的,只能通过 cookie, session 来获取状态。那么Django登录一定是在 session 中做文章。于是把 Django 的session变为 dict 查看,发现了问题
session 中存在 _auth_user_id,但是 request.user=AnonymousUser: AnonymousUser
dict_items([(‘_auth_user_backend‘, ‘apps.traffic.backends.WeixinAccessTokenAuthenticationBackend‘), (‘openid‘, ‘ouRGywq5gA9bTyMvAw-JcovC6M00‘), (‘_auth_user_id‘, ‘254‘), (‘_auth_user_hash‘, ‘2f27f6ec2895b333caa320790f7868d87094017c‘), (‘code‘, ‘0412PZ1T1Uj85a1HGK1T1BvY1T12PZ1o‘), (‘_session_expiry‘, 2592000)])
于是又问同事,他说是 Django 中间件那里过不了。我看了下 backend,能通过 authenticate 获取 user 啊。没办法,再次 Google "django session and login in",这里http://eli.thegreenplace.net/2011/07/17/django-sessions-part-iii-user-authentication 说道
Auth middleware
Similarly to the path we‘ve taken with sessions, it‘s instrumental to first see how authentication middleware is implemented. Or in other words, how did the "user" attribute get into my HTTP request?The answer is in contrib/auth/middleware.py [2]:
class LazyUser(object): def __get__(self, request, obj_type=None): if not hasattr(request, ‘_cached_user‘): from django.contrib.auth import get_user request._cached_user = get_user(request) return request._cached_user
于是搜索显示调用 `get_user(request)`发现返回的是 None,通过 Pycharm 打断点进去看,确认问题出在自定义 backend 上面,其中的 get_user 方法没有返回 user 对象,返回的是 None。问题终结!
反思一下为什么解决这个问题花了这么长时间:
没有规矩。
找 bug 随便找,并没有指定很好的方案。一直在 login 那里打转,不相信是其他的问题。
如果再让我来一次,我会调整为:
按照靠谱程度找 bug。自定义的代码比 Django 源码更不靠谱,所以先重点关注自定义的代码。
从底层入手。authenticate 的实现机制是什么,然后一层层往上。
认真的看代码,可以从下往上看,提高关注度,而不是扫一遍,觉得大概是没错的。
看一遍Django自定义 backend 是怎么写的,并与已有代码比较。
找完了 bug,进入正文。
Django 的认证方式:
middleware, 自定义基类, 装饰器以及Mixin
middleware
middleware 是笼罩所有视图的,比如我这有一个充值话费的项目,就使用了 middleware 来进行验证
自定义基类
自定义基类,我之前用过,感觉不灵活,是我自己想出来的,与 Django 的体系应该不同
装饰器以及Mixin
这个也属于 Django 的体系,也是我们常用的。有些页面需要登录就加装饰器,有些不需要就不加。
以上是关于Django authenticate() 函数查找不到与提交的用户名和密码匹配的用户,则会返回 None。的主要内容,如果未能解决你的问题,请参考以下文章
authenticate()和login()实现用户登录 | Django
Django authenticate() 函数查找不到与提交的用户名和密码匹配的用户,则会返回 None。