python - 如何使用任何 url 上的查询参数对用户进行身份验证?

标签 python django django-authentication django-login

假设用户登陆 https://example.com/any/page?token=hhdo28h3do782

使用查询字符串对用户进行身份验证和登录的推荐方法是什么?

我正在考虑创建某种调用 authenticate() 的包罗万象的 View (我也想知道如何做到这一点 :D)。然后我会建立一个自定义后端来验证用户。

这是实现我想要的理想方式吗?

干杯!

最佳答案

为此,您需要 create a custom authentication backend验证 api key 。

在此示例中,请求 自动检查有效 token 。您根本不需要修改您的观点。这是因为它包含对用户进行身份验证的自定义中间件。

为简洁起见,我假设有效的用户 token 存储在一个模型中,该模型是 django auth.User 模型的外键。

# my_project/authentication_backends.py
from django.contrib import auth
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
from django.contrib.auth.middleware import AuthenticationMiddleware

TOKEN_QUERY_PARAM = "token"

class TokenMiddleware(AuthenticationMiddleware):
    def process_request(self, request):
        try:
            token = request.GET[TOKEN_QUERY_PARAM]
        except KeyError:
            # A token isn't included in the query params
            return

        if request.user.is_authenticated:
            # Here you can check that the authenticated user has the same `token` value
            # as the one in the request. Otherwise, logout the already authenticated
            # user.
            if request.user.token.key == token:
                return
            else:
                auth.logout(request)

        user = auth.authenticate(request, token=token)
        if user:
            # The token is valid. Save the user to the request and session.
            request.user = user
            auth.login(request, user)

class TokenBackend(ModelBackend):
    def authenticate(self, request, token=None):
        if not token:
            return None

        try:
            return User.objects.get(token__key=token)
        except User.DoesNotExist:
            # A user with that token does not exist
            return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

现在,除了任何现有的后端或中间件之外,您还可以在 settings.py 中添加到 AUTHENTICATION_BACKENDSMIDDLEWARE 的路径已经有。如果您使用的是默认值,它将如下所示:

MIDDLEWARE = [
    # ...
    "django.contrib.auth.middleware.AuthenticationMiddleware",

    # This is the dotted path to your backend class. For this example,
    # I'm pretending that the class is in the file:
    #     my_project/authentication_backends.py
    "my_project.authentication_backends.TokenMiddleware",

    # ...
]

AUTHENTICATION_BACKENDS = [
    "django.contrib.auth.backends.ModelBackend",
    "my_project.authentication_backends.TokenBackend",
]

关于python - 如何使用任何 url 上的查询参数对用户进行身份验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62024580/

相关文章:

python - 如何让 Python 代码在 telnet (telnetlib) 超时后继续

python - 在主脚本之外使用 python 多进程

python - 同一页面上的重复占位符

python - Django-Twilio 在按钮单击时发送短信

创建用户然后登录的Django问题

django - “用户”对象没有属性is_authenticated

python - 仅使用变量通过 python 对 sqlite 表进行建模

python - pd.DataFrame 中的 Nan(对称矩阵)

django - 我需要在 Django 的整体布局和标题上使用 'load static' 两次吗?

django - 如何在Django身份验证生成的页面中启用https?