Python社区  »  问与答

[精华] authenticate()不能检验password

Dingo • 5 年前 • 14750 次点击  

使用authenticate()验证用户登录时,只能检验username。

部分代码:

user=authenticate(username=cduser['username'],password=cduser['password'])
if user is not None:
    return HttpResponse('success')
else:
    return HttpResponse('wrong')

现在情况是:登陆界面 输入username和password,提交表单以后, 如果username不存在,可以返回wrong。 如果username存在,不论password是什么,点击提交按钮在原页面停留,不会返回wrong或success。

AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', )设置过了

用的User.objects.create_user创建用户,密码应该是hash了的,在/admin里面看密码是hash了的。

cduser里储存的username和password是对的,我打印过。

求大神解决,十分感谢!

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/399
 
14750 次点击  
分享到微博
文章 [ 17 ]  |  最新文章 3 年前
1339984168
Reply   •   1 楼
1339984168    3 年前

这是我的代码 def login(request):

# uname = request.POST.get('username')
# pword = request.POST.get('password')
user=authenticate(username='zhujun',password='123456')
print user
reply={}
if user is not None:
    reply['status'] = 1
    print ('login in successfully.')
else:
    reply['status'] = 0
    print ('login in failed.')
return HttpResponse(json.dumps(reply), content_type="application/json")
1339984168
Reply   •   2 楼
1339984168    3 年前

我也是这段代码出了问题,不管是设置默认值还是通过POST,GET获取的用户名密码 ,都显示user是none,所以每次都匹配到错误的部分,不解,同时,我想问的是我没有用is_active字段,这段代码就是检测用户名是否存在的问题吗?只要有用户名就可以?怎么和数据库交互的啊。求大神指点

Py站长
Reply   •   3 楼
Py站长    5 年前

@Dingo 赞!

Dingo
Reply   •   4 楼
Dingo    5 年前

已经解决了。问题主要是is_valid()。一般情况下,自己写一个form,然后调用其is_valid()的方法,只会检查表单输入是否符合格式,比如是不是超出定义的长度限制。而我用的是django自带的表单:

from django.contrib.auth.models import User
class UserForm(ModelForm):
    class Meta:
        model = User
        fields = ['username', 'password']

直接使用django自带的user的话,它的is_valid()是重写了的,调用is_valid()就不单单是检查表单格的格式了,还要检查是否有重复用户。所以注册的表单用它的user比较好,可以防止重复的注册。登陆的表单就不要用了,用自己写的吧。 谢谢各位的回答。

Py站长
Reply   •   5 楼
Py站长    5 年前

囧。。

三画儿
Reply   •   6 楼
三画儿    5 年前

你的 if ruser.is_valid():通过验证了么

Dingo
Reply   •   7 楼
Dingo    5 年前

我也被这问题弄晕了。问题的关键是,函数为什么不是必然执行的。因为login()是表单页面的处理函数,所以不论表单怎么填写,都应该执行函数。执行函数的话“return HttpResponse(user)# 这里应该会出错”这句一定会执行到。但是用户名存在的话,根本没有执行这句话。说明很有可能没有执行函数。为什么不执行函数呢?我也晕了

三画儿
Reply   •   8 楼
三画儿    5 年前

你这直接把我说晕了
authenticate 函数 会先从库里找出 username='abc'的 然后再去检查你的密码是否是123 如果用户名和密码输入正确返回的是一个user对象 如果不正确会返回一个None 怎么用户名输入不正确反而可以打印'abc'呢...
还有就是如果只是简单的登录可以直接用django自带的

Dingo
Reply   •   9 楼
Dingo    5 年前

唉,我发现了个更奇怪的事情。整个函数如下

def login(request):
    if request.method == 'POST':
        ruser = UserForm(request.POST)
        if ruser.is_valid():
            cduser = ruser.cleaned_data    
            #user=authenticate(username='abc',password='123') 这里注释了
            return HttpResponse(user)# 这里应该会出错
            if user is not None:
                return HttpResponse('success')
            else:
                return HttpResponse('wrong')
    else:
        ruser = UserForm()
    return render_to_response('login.html',{'user':ruser},context_instance=RequestContext(request))

当表单用户名不存在时,的确会出错。但是用户名存在的话,仍然停留在原界面。而且从服务器请求记录来看,两种情况都收到了POST的请求。

Dingo
Reply   •   10 楼
Dingo    5 年前

对,不过和密码没有关系。只要用户名不对,就可以打印,用户名数据库里有的话就不能打印。

三画儿
Reply   •   11 楼
三画儿    5 年前

你的意思是用户名和密码输入正确的话 停留在原页面? 输入不正确的时候反而打印出用户名?

Dingo
Reply   •   12 楼
Dingo    5 年前
user=authenticate(username='abc',password='123') 
return HttpResponse(user)
if user is not None:
    return HttpResponse('success')
else:
    return HttpResponse('wrong')

试了一下,结果这样,当表单用户名不是abc时,返回的页面是abc。用户名是abc时,停留在原页面。就是说后者程序没有运行到第一个return。而且只要是数据库里有的用户名提交表单后都停留在原页面。

三画儿
Reply   •   13 楼
三画儿    5 年前

如果 username:abc password:123的时候 你打印下user能返回一个abc么

Dingo
Reply   •   14 楼
Dingo    5 年前

经测试,与浏览器和系统无关。可能是缓存之类的?

Dingo
Reply   •   15 楼
Dingo    5 年前

现在是这样的:

user=authenticate(username='abc',password='123') #这个用户存在
if user is not None:
    return HttpResponse('success')
else:
    return HttpResponse('wrong')

然后每次提交表单都应该显示success吧。 可我的实际情况是,若用户名不是abc,提交表单后可以到success页面。若用户名是abc,提交后停留在原页面。这样的情况很奇怪。我用的是火狐11.0,ubuntu12.04.

Dingo
Reply   •   16 楼
Dingo    5 年前

如果认证成功,它返回一个 User 对象。 如果密码无效,它返回一个 None 。 是这样吗?

Py站长
Reply   •   17 楼
Py站长    5 年前

user=authenticate(username=cduser['username'],password=cduser['password'])

你这句的返回值是什么?