0

我正在尝试使用 Django,并尝试创建一个登录/注册应用程序。这就是我卡住的地方——我可以注册用户,但是我不能用他们登录。这是我认为相关的代码:

视图.py

def login(request, template='accounts/sign_in.html'):
    if request.user.is_authenticated():
        return redirect(reverse('games'))
    if request.method == 'POST':
        post = request.POST.copy()
        if 'password' in post:
            post['password'] = make_password(post['password'])
        form = AuthenticationForm(data=post)

        if form.is_valid():
            login(request, form.get_user())
            messages.success(
                request, "Successfully logged in.", extra_tags='success')
            return redirect(reverse('games'))
        else:
            messages.warning(
                request, "Wrong username or password." + request.POST['username'] + " " + request.POST['password'], extra_tags='error')
            return redirect(reverse('login'))
    return views.login(request, template)

def register(request, template='accounts/sign_up.html'):
    if request.user.is_authenticated():
        return redirect(reverse('home'))
    if request.method == 'POST':
        form = RegisterForm(request.POST)
        if form.is_valid():
            new_user = User(
                username=form.cleaned_data['username'],
                password=make_password(form.cleaned_data['password1']),
                is_active=True,
            )
            new_user.save()

            messages.success(request, "Your account was successfully created.")
            return redirect(reverse('games'))
    else:
        form = RegisterForm()

    return render(request, template, {'register_form': form})

当我尝试使用我创建的用户(用户名:qwe,密码:qweqweqwe)登录时,我会重新登录以再次登录,但消息中会打印完全相同的用户名和密码:

Wrong username or password.qwe qweqweqwe

但是,当我尝试交互式 shell 时,我得到了以下结果:

>>> User.objects.all()
[<User: admin>, <User: asd>, <User: qwe>]
>>> User.objects.all()[2]
<User: qwe>
>>> User.objects.all()[2].password
u'pbkdf2_sha256$10000$HM2k6uDntJ68$DLqHKcGxtJG7pJC7tbZcm29vB88LEgaw2xroqZEkTFw='

所以我有这样一个用户,它是一个有效的帐户。

4

2 回答 2

1

我很确定你不需要调用make_password这个:

if 'password' in post:
    post['password'] = make_password(post['password'])
form = AuthenticationForm(data=post)

只需将正常传递request.POSTdata表单,表单本身就会进行加密并针对数据库进行测试。这是它执行此操作AuthenticationForm的方法的片段:clean

def clean(self):
    username = self.cleaned_data.get('username')
    password = self.cleaned_data.get('password')

    if username and password:
        self.user_cache = authenticate(username=username,
                                       password=password)
    ...

你可以在这里看到完整的定义。

我想您使用的是官方make_password功能,django.contrib,auth但请仔细查看文档,通常,用户注册功能会自动执行此操作,因此您不必这样做。

无论如何:

在调用后检查错误表单是否产生is_valid并将您的login代码更改为:

if request.method == 'POST':
    form = AuthenticationForm(data=request.POST)

希望这可以帮助!

于 2013-06-01T23:41:44.987 回答
0

问题编号 1 - 错误login()

这大概就是问题所在:

login(request, form.get_user())

你已经有了一个login函数,它恰好是一个视图。我想您想确认用户身份验证(form.is_valid()不会自动执行此操作)。

更多详细信息在模块的文档中auth

如何让用户登录

如果您有想要附加到当前会话的经过身份验证的用户 - 这是通过login()函数完成的。

登录()

要从视图中登录用户,请使用login(). 它需要一个 HttpRequest 对象和一个 User 对象。login()使用 Django 的会话框架将用户的 ID 保存在会话中。

请注意,匿名会话期间的任何数据集都会在用户登录后保留在会话中。

此示例显示了如何同时使用authenticate()login()

from django.contrib.auth import authenticate, login

def my_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            # Redirect to a success page.
        else:
            # Return a 'disabled account' error message
    else:
        # Return an 'invalid login' error message.

问题编号 2 - 密码错误

正如 Paulo 提到的,AuthenticationForm已经处理了密码散列。示例请阅读官方文档:

使用 Django 身份验证系统:Web 请求中的身份验证

于 2013-06-01T23:45:11.870 回答