简体   繁体   English

第一个 django rest api 调用返回 request.user 作为 AnonymousUser 但进一步调用返回正确的用户

[英]First django rest api call returns request.user as AnonymousUser but further calls return proper user

right now I have an api view that requires knowing which user is currently logged in. When I try to call it with a logged in user;现在我有一个 api 视图,需要知道当前登录的用户。当我尝试使用登录用户调用它时; however, it returns anonymous user.但是,它返回匿名用户。 The odd thing is that if I call the api view again, it returns the proper user.奇怪的是,如果我再次调用 api 视图,它会返回正确的用户。 I am using django rest framework and JSON Web Tokens with simplejwt.我正在使用 django rest 框架和 JSON ZC6E190B284633C48E39E55049jwts.CCE Right now the call in ReactJS looks like this:现在 ReactJS 中的调用如下所示:

const fetchAuthorData = () => {
        axiosInstance.get('authors/')
        .then((res) => {
            setAuthor(res.data)
        }).catch((err) => {
            fetchAuthorData()
        })
        
        fetchAuthorThreads()
        fetchAuthorArticles()
    }

However, I know recursively calling this over and over is very dangerous, because even though I redirect if the user is actually not logged in before this recursive api call, if somehow that fails my server will be overloaded with api calls.但是,我知道一遍又一遍地递归调用它是非常危险的,因为即使我重定向如果用户在此递归 api 调用之前实际上没有登录,如果以某种方式失败,我的服务器将因 api 调用而过载。 Does anyone know how I could make it so that my api actually properly identifies on the first call whether the user is logged in?有谁知道我怎样才能做到这一点,以便我的 api 在第一次通话时正确识别用户是否登录?

Here is my login view:这是我的登录视图:

axiosInstance.post('author-auth/token/', {
                email: formData.email,
                password: formData.password,
            }).then((response) => {
                localStorage.setItem('access_token', response.data.access)
                localStorage.setItem('refresh_token', response.data.refresh)
                axiosInstance.defaults.headers['Authorization'] = 
                    'JWT ' + localStorage.getItem('access_token')
                    history.push('/')
            }).catch((err) => {
                alert("Make Sure Login Credentials Are Correct")
            })

Here is the faulty view:这是错误的视图:

@api_view(['GET'])
def author(request):
    print(request.user)
    if request.user.is_authenticated:
        author = request.user
        serializer = AuthorAccessSerializer(author, many=False)
        return Response(serializer.data)
    else:
        return HttpResponse(status=400)

In this, request.user is an anonymous user even though I am logged in在此, request.user 是匿名用户,即使我已登录

Here is a similar part of another view that works oddly这是另一个奇怪的视图的类似部分

@api_view(['GET', 'POST'])
def articles(request):
    if request.method == 'GET':
        category_name = request.query_params['category']
        dash = request.query_params['dash']
        #this part is very similiar and works for some reason
        if dash == "True":
            if request.user.is_authenticated:
                articles = Article.objects.filter(author=request.user)
            else:
                return HttpResponse(status=401)
        # *end part*
        elif category_name:
            try:
                category = Category.objects.get(name__icontains=category_name)
            except:
                return HttpResponse(status=400, content="Category not found")
            articles = Article.objects.filter(category=category)
        else:
            articles = Article.objects.all()
        serializer = ArticleSerializer(articles, many=True)
        
        return Response(serializer.data)

Here are my axios settings:这是我的 axios 设置:

export const axiosInstance = axios.create({
    baseURL: baseURL,
    timeout: 5000,
    headers : {
        Authorization: localStorage.getItem('access_token')
            ? 'JWT' + localStorage.getItem('access_token')
            : null,
        'Content-Type' : 'application/json',
        accept : 'application/json'
    }
})

And here are my rest framework and JWT auth settings:这是我的 rest 框架和 JWT 身份验证设置:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny'
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(hours=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': False,
    'BLACKLIST_AFTER_ROTATION': True,
    'UPDATE_LAST_LOGIN': False,

    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUDIENCE': None,
    'ISSUER': None,
    'JWK_URL': None,
    'LEEWAY': 0,

    'AUTH_HEADER_TYPES': ('Bearer', 'JWT'),
    'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
    'USER_ID_FIELD': 'id',
    'USER_ID_CLAIM': 'user_id',
    'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',

    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',

    'JTI_CLAIM': 'jti',

    'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
    'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}

ALLOWED_HOSTS=['127.0.0.1', 'http://localhost:5000']
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = (
    'http://localhost:3000',
) 

Again, if I keep calling the same api call, it works for some reason not changing any authorization headers, tokens, or anything else and request.user works fine with the second view I have above.同样,如果我继续调用相同的 api 调用,由于某种原因,它不会更改任何授权标头、令牌或其他任何内容,并且 request.user 可以在上面的第二个视图中正常工作。 Can anyone tell me why this is happening?谁能告诉我为什么会这样?

I think,我认为,

                1. localStorage.setItem('access_token', response.data.access)
                2. localStorage.setItem('refresh_token', response.data.refresh)
                3. axiosInstance.defaults.headers['Authorization'] = 
                    'JWT ' + localStorage.getItem('access_token')
                    history.push('/')

on login code may cause problem.登录代码可能会导致问题。

These code never run sequentially;这些代码从不按顺序运行; every javascript run asynchronously.每个 javascript 异步运行。

It means, your axiosInstance.defaults.headers could be null because, 1, 2 and 3 lines are executed at once.这意味着,您的axiosInstance.defaults.headers可能是 null 因为一次执行 1、2 和 3 行。 In other words, axiosInstance.defaults.headers become null (as there is no access_token on localStorage) then, Js set access_token from response.data.access .也就是说axiosInstance.defaults.headers变成 null (因为 localStorage 上没有 access_token )然后,Js 从response.data.access设置 access_token 。

You'd better use promise with .then() after 1 and 2 line, or fetch Authorization of axiosInstance when make http request.您最好在第 1 行和第 2 行之后将 promise 与 .then .then()一起使用,或者在发出 http 请求时获取 axiosInstance 的授权。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法使用django rest框架进行身份验证(request.user = AnonymousUser) - Not able to authenticate using the django rest framework (request.user = AnonymousUser) Django oauth2 request.user返回AnonymousUser - Django oauth2 request.user returns AnonymousUser 在 Django 和 DRF 中,为什么 api 路由 request.user 会返回一个 AnonymousUser 实例,而 django.contrib.auth.get_user(request) 会返回用户? - In Django and DRF, why would an api route request.user return an AnonymousUser instance, while django.contrib.auth.get_user(request) return the user? Django request.user在第三方重定向后成为AnonymousUser - Django request.user become AnonymousUser after third party redirect AbstractUser 上的 request.user 给出 AnonymousUser TypeError - request.user on AbstractUser gives AnonymousUser TypeError 登录门户后,在我的 Django 门户中,我的 request.user 始终提供值 AnonymousUser - In my Django portal after login to the portal my request.user is always giving the value AnonymousUser 获取用户在Django上返回“ AnonymousUser” - get user returns “AnonymousUser” on django Allauth request.user 在 APIView 中是 AnonymousUser,但在 View 中 is_authenticated - Allauth request.user is AnonymousUser in APIView, but is_authenticated in View Django request.user是空的 - Django request.user is empty 在django rest框架中使用request.user进行模型反序列化 - Use request.user for model deserialization in django rest framework
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM