我想为我的Django 1.11项目创建一个身份验证。如果请求包含标头<button>
,则将对用户进行身份验证。
我正在使用通用视图,因此我使用X_USERNAME
来控制访问。
我做了这个自定义身份验证类:
LoginRequiredMixin
我在设置中添加了它:
class CustomAuthentication:
def authenticate(self, request):
username = request.META.get('X_USERNAME')
logging.warning(username)
if not username:
return None
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
user = User(username=username)
user.is_staff = False
user.is_superuser = False
if request.META.get('X_GROUPNAME') == 'administrator':
user.is_staff = True
user.is_superuser = True
user.save()
return user, None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
但是我无法使其工作。我被重定向到不存在的AUTHENTICATION_BACKENDS = ['path.to.file.CustomAuthentication']
。
谢谢!
编辑:
我也尝试创建一个子类,如下所述:Django RemoteUser documentation,因为它看起来像我想要实现的:
/accounts/login/?next=
它给了我相同的结果。
答案 0 :(得分:0)
似乎authenticate()
方法除了username
参数外还必须指定password
和request
参数。没有这些,Django将忽略后端(请参阅Django 2.0中的django.contrib.auth.__init__._authenticate_with_backend
)。
由于您要通过标头提供用户名,因此您应该能够将这些参数默认设置为None
。
class CustomAuthentication:
def authenticate(self, request, username=None, password=None):
username = request.META.get('X_USERNAME')
...
或者,使用**credentials
:
def authenticate(self, request, **credentials):
答案 1 :(得分:0)
我终于设法找到了解决方法:
在authentication.py中:
from django.contrib.auth.middleware import RemoteUserMiddleware
from django.contrib.auth.middleware import RemoteUserBackend
class CustomMiddleware(RemoteUserMiddleware):
header = 'HTTP_X_USERNAME'
第二次输入是强制性的,我不确定为什么。
在settings.py中:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'app.authentication.CustomMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
AUTHENTICATION_BACKENDS = ['app.authentication.RemoteUserBackend']
最后在基于类的视图中,我使用LoginRequiredMixin