如何添加Authenticate Middleware JWT django?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何添加Authenticate Middleware JWT django?相关的知识,希望对你有一定的参考价值。

我正在尝试创建一个中间件来使用JWT进行身份验证,但在视图中,request.user始终是AnonymUser。

当我验证中间件通过用户模型更改request.user时,它确实如此,但在到达视图时,由于某种原因,request.user始终是anonymousUser

我正在使用Django 1.11

# coding=utf-8
from django.utils.functional import SimpleLazyObject
from django.utils.deprecation import MiddlewareMixin
from django.contrib.auth.models import AnonymousUser, User
from django.conf import settings
from django.contrib.auth.middleware import get_user
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
import jwt
import json


class JWTAuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.user = SimpleLazyObject(lambda: self.__class__.get_jwt_user(request))

    @staticmethod
    def get_jwt_user(request):
        user_jwt = get_user(request)
        if user_jwt.is_authenticated():
            return user_jwt
        token = request.META.get('HTTP_AUTHORIZATION', None)
        user_jwt = None
        if token is not None:
            try:
                user_jwt = jwt.decode(
                    token,
                    settings.SECRET_KEY,
                    algorithms=['HS256']
                )
                user_jwt = User.objects.get(
                    id=user_jwt['user_id']
                )
            except Exception as e:
                user_jwt = AnonymousUser
        return user_jwt





MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
     'django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'user.middlewares.JWTAuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
答案

试试这个中间件:

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'applications.custom_authentication.middleware.JWTAuthenticationMiddleware', # This is my middleware
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

另一答案

我试图复制你的错误,但在我的情况下,它运作良好,我认为你的问题的根本原因是异常处理方法。 jwt.decode可以引发多种类型的异常,包括DecodeErrorExpiredSignatureErrorInvalidKeyError等等,甚至从jwt.decode检索到的dict都没有'user_id'键。

这是一个完全有效的代码

# coding=utf-8
import jwt
import traceback

from django.utils.functional import SimpleLazyObject
from django.utils.deprecation import MiddlewareMixin
from django.contrib.auth.models import AnonymousUser, User
from django.conf import LazySettings
from django.contrib.auth.middleware import get_user

settings = LazySettings()


class JWTAuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.user = SimpleLazyObject(lambda: self.__class__.get_jwt_user(request))

    @staticmethod
    def get_jwt_user(request):

        user_jwt = get_user(request)
        if user_jwt.is_authenticated():
            return user_jwt
        token = request.META.get('HTTP_AUTHORIZATION', None)

        user_jwt = AnonymousUser()
        if token is not None:
            try:
                user_jwt = jwt.decode(
                    token,
                    settings.WP_JWT_TOKEN,
                )
                user_jwt = User.objects.get(
                    id=user_jwt['data']['user']['id']
                )
            except Exception as e: # NoQA
                traceback.print_exc()
        return user_jwt

只需要考虑几个因素,使用LazySettings设置Check this thread总是一个好习惯

这也是我的中间件订单

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'applications.custom_authentication.middleware.JWTAuthenticationMiddleware', # This is my middleware
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

请记住在django.contrib.auth.middleware.AuthenticationMiddleware中间件之后放置您的自定义中间件

以上是关于如何添加Authenticate Middleware JWT django?的主要内容,如果未能解决你的问题,请参考以下文章

我是不是必须在学生表中添加 password_digest 列才能使 student.authenticate(password) 运行?即使我使用的是设计?

passport.authenticate()如何确定successRdirect或failureRedirect?

Social.localUser.Authenticate 回调从未被调用

如何在 Spring Security Grails 上自定义 /login/authenticate?

django 的auth.authenticate返回为None

如何解决 Nestjs 中的“策略#authenticate 必须被子类覆盖”错误