Django 自定义身份验证后端似乎没有被调用?
Django custom auth backend doesn't seem to be being called?
我在 Python 3 上使用 Django 1.8.4,并尝试创建一个身份验证后端来验证来自遗留 ColdFusion 网站的 cookie,并在检查值后创建/登录 Django 用户在数据库中。在设置中,我包括后端:
AUTHENTICATION_BACKENDS = (
'site_classroom.cf_auth_backend.ColdFusionBackend',
)
以及后端本身的代码; SiteCFUser 是针对 SQL 服务器数据库用户模型的模型,其中包含活动 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 时,后端似乎没有被调用,甚至试图通过带有用户名和密码的表单登录。如果我通过在设置中更改 class 的名称或在 cf_auth_backend.py 中更改 class 的名称来强制出错,我确实会收到错误。但是,none 的打印语句显示在控制台中。我显然在这里遗漏了一些东西:知道我做错了什么吗?
身份验证后端不是那样工作的。不会针对每个请求或需要身份验证的请求调用它们。
如果你想根据一些cookie来登录用户,你应该在中间件中调用认证。
虽然接受的答案可能对 OP 有所帮助,但它并不是问题标题的一般答案。
身份验证后端 do 只需将它们列在 AUTHENTICATION_BACKENDS
中即可工作。但它们可能看起来被忽略了
由于各种原因,例如:
urls.py 需要指向类似 django.contrib.auth.views.login
的内容
url(r'^accounts/login/$', django.contrib.auth.views.login)
如果它指向其他一些身份验证应用程序。 AUTHENTICATION_BACKENDS
可能不工作。
authenticate()
方法必须接受 password
关键字,或者通过
password=None
或 **kwargs
。 username
可能也是如此。它不会
如果它不接受该关键字参数,则被调用。
我在 Python 3 上使用 Django 1.8.4,并尝试创建一个身份验证后端来验证来自遗留 ColdFusion 网站的 cookie,并在检查值后创建/登录 Django 用户在数据库中。在设置中,我包括后端:
AUTHENTICATION_BACKENDS = (
'site_classroom.cf_auth_backend.ColdFusionBackend',
)
以及后端本身的代码; SiteCFUser 是针对 SQL 服务器数据库用户模型的模型,其中包含活动 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 时,后端似乎没有被调用,甚至试图通过带有用户名和密码的表单登录。如果我通过在设置中更改 class 的名称或在 cf_auth_backend.py 中更改 class 的名称来强制出错,我确实会收到错误。但是,none 的打印语句显示在控制台中。我显然在这里遗漏了一些东西:知道我做错了什么吗?
身份验证后端不是那样工作的。不会针对每个请求或需要身份验证的请求调用它们。
如果你想根据一些cookie来登录用户,你应该在中间件中调用认证。
虽然接受的答案可能对 OP 有所帮助,但它并不是问题标题的一般答案。
身份验证后端 do 只需将它们列在 AUTHENTICATION_BACKENDS
中即可工作。但它们可能看起来被忽略了
由于各种原因,例如:
urls.py 需要指向类似
的内容django.contrib.auth.views.login
url(r'^accounts/login/$', django.contrib.auth.views.login)
如果它指向其他一些身份验证应用程序。
AUTHENTICATION_BACKENDS
可能不工作。authenticate()
方法必须接受password
关键字,或者通过password=None
或**kwargs
。username
可能也是如此。它不会 如果它不接受该关键字参数,则被调用。