【问题标题】:Django custom auth backend doesn't seem to be being called?似乎没有调用 Django 自定义身份验证后端?
【发布时间】:2023-04-01 12:43:01
【问题描述】:

我在 Python 3 上使用 Django 1.8.4,并尝试创建一个身份验证后端,该后端验证来自旧版 ColdFusion 网站的 cookie,并在检查数据库中的值后创建/登录 Django 用户。在设置中,我包括后端:

AUTHENTICATION_BACKENDS = (
    'site_classroom.cf_auth_backend.ColdFusionBackend',
)

以及后端本身的代码; SiteCFUser 是针对 SQL Server 数据库用户模型的模型,其中包含活动 cookie 令牌值:

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model
from users.models import SiteCFUser


class ColdFusionBackend(ModelBackend):
    """
    Authenticates and logs in a Django user if they have a valid ColdFusion created cookie.

    ColdFusion sets a cookie called "site_web_auth"
    Example cookie: authenticated@site+username+domain+8E375588B1AAA9A13BE03E401A02BC46
    We verify this cookie in the MS SQL database 'site', table site_users, column user_last_cookie_token
    """

    def authenticate(self, request):
        User = get_user_model()

        print('Hello!')
        token=request.COOKIES.get('site_web_auth', None)
        print('Token: ' + token)
        cookie_bites = token.split('+')

        if cookie_bites[0] != "authenticated@site":
            # Reality check: not a valid site auth cookie
            return None

        username = cookie_bites[1]
        cf_token = cookie_bites[3]

        try:
            site_user = SiteCFUser.objects.using('mssqlsite').filter(cf_username=username)
        except:
            # No user found; redirect to login page
            return None

        if site_user[0].cftoken == cf_token:
            try:
                # Does the user exist in Django?
                user = User.objects.get(username=username)
            except:
                # User does not exist, has a valid cookie, create the User.
                user = User(username=username)
                user.first_name = site_user[0].cf_first_name
                user.last_name = site_user[0].cf_last_name
                user.email = site_user[0].cf_email
                user.save()
        else:
            return None

    def get_user(self, user_id):
        User = get_user_model()

        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

问题是,当使用@login_required 访问带有视图的 URL 时,或者甚至尝试使用用户名和密码通过表单登录时,似乎没有调用后端。如果我通过更改设置中的类名来强制出错,或者更改 cf_auth_backend.py 中的类名,我会收到错误消息。但是,控制台中没有显示任何打印语句。我显然在这里遗漏了一些东西:知道我做错了什么吗?

【问题讨论】:

  • 如果用户尚未通过身份验证,所有@login_required 所做的都是重定向到登录页面。您需要显示该视图的代码。

标签: python django django-models django-authentication django-class-based-views


【解决方案1】:

虽然接受的答案可能对 OP 有所帮助,但这并不是对问题标题的一般答案。

身份验证后端只需将它们列在AUTHENTICATION_BACKENDS 中即可。但它们似乎被忽略了 由于各种原因,例如:

  • urls.py 需要指向类似django.contrib.auth.views.login

    url(r'^accounts/login/$', django.contrib.auth.views.login)
    

    如果它指向其他一些身份验证应用程序。 AUTHENTICATION_BACKENDS 可能不起作用。

  • authenticate() 方法必须接受 password 关键字,或者通过 password=None**kwargsusername 也可能如此。它不会 如果它不接受该关键字参数,则调用它。

【讨论】:

  • 感谢您的第二个提示!我从一个旧的示例后端开始,它没有 authenticate 的更新函数签名。
  • 两年后才偶然发现这个问题……看来authenticate的方法签名又变了,现在好像需要request参数。
【解决方案2】:

身份验证后端不能那样工作。不会在每个请求或需要身份验证的请求上调用它们。

如果你想基于一些cookie登录用户,你应该在中间件中调用身份验证。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2021-02-06
    • 2018-02-24
    • 2019-01-23
    • 2020-11-17
    • 2015-07-31
    • 2016-11-07
    相关资源
    最近更新 更多