Django: обновите и установите JWT как файл cookie HttpOnly с помощью промежуточного программного обеспечения. Response (), возвращающий django.template.response.ContentNotRenderedError

У меня есть специальное промежуточное ПО, в которое я добавляю SimpleJWR HTTP_AUTHORIZATION ко всем авторизованным запросам, поскольку я использую HttpOnly файлы cookie. Также здесь я добавил код, чтобы проверить, действителен ли токен access. Если нет, то запрос отправляется с использованием requests, который извлекает новый access токен и устанавливает его как HttpOnly cookie. Пока что я могу получить новый токен access по истечении срока его действия. Но URL-адрес, с которого я отправил запрос, возвращает эту ошибку:

raise ContentNotRenderedError(
django.template.response.ContentNotRenderedError: The response content must be rendered before it can be accessed.

По первому запросу работает. Он возвращает ответ и сохраняет токены как HttpOnly cookie, но после истечения срока действия токена, и если я снова сделаю запрос, вместо (того, что я хочу) сохранить токены как HttpOnly cookie и снова вернуть тот же ответ, он возвращает ошибка.

Я думаю, что проблема в response заявлениях. Мое промежуточное ПО:

import jwt
import datetime
import requests
import json

from rest_framework.response import Response
from django.conf import settings

class AuthorizationHeaderMiddleware:
    def __init__(self, get_response=None):
        self.get_response = get_response

    def __call__(self, request):
        access_token = request.COOKIES.get('access')
        refesh_token = request.COOKIES.get('refresh')
        print(refesh_token)
        # check if the access token is valid
        # if not, send new access token to cookie
        if access_token:
            key = settings.SECRET_KEY
        try:
            decoded_access_token = jwt.decode(access_token, key, algorithms=["HS256"])
        except jwt.ExpiredSignatureError:
            # Signature has expired
            print("expired; sending for new token")
            url = 'http://127.0.0.1:8000/api/token/refresh/'
            data = {"refresh": refesh_token}
            resp = requests.post(
                url, 
                data=json.dumps(data),
                headers = {'content-type': 'application/json'}
                )
            result = resp.json()
            new_access_token = result['access']
            response = Response()
            response.set_cookie('access', new_access_token, httponly=True)
            response.set_cookie('set', 'new')
            return response

            request.META['HTTP_AUTHORIZATION'] = f'Bearer {access_token}'
        return self.get_response(request)

Как возникает эта ошибка и как ее исправить?




Ответы (1)


Попробуй это:

def __call__(self, request):
    access_token = request.COOKIES.get('access')
    refesh_token = request.COOKIES.get('refresh')
    print(refesh_token)
    # check if the access token is valid
    # if not, send new access token to cookie
    if access_token is not None:
        key = settings.SECRET_KEY
    else:
        return Response({"Error" : "No token found"})
    try:
        decoded_access_token = jwt.decode(access_token, key, algorithms=["HS256"])
        request.META['HTTP_AUTHORIZATION'] = f'Bearer {access_token}'
        return self.get_response(request)
    except jwt.ExpiredSignatureError:
        # Signature has expired
        print("expired; sending for new token")
        url = 'http://127.0.0.1:8000/api/token/refresh/'
        data = {"refresh": refesh_token}
        resp = requests.post(
            url, 
            data=json.dumps(data),
            headers = {'content-type': 'application/json'}
            )
        result = resp.json()
        new_access_token = result['access']
        response = Response()
        response.set_cookie('access', new_access_token, httponly=True)
        response.set_cookie('set', 'new')
        request.META['HTTP_AUTHORIZATION'] = f'Bearer {new_access_token}'
        
        return self.get_response(request)
person Pradip    schedule 17.02.2021
comment
После добавления я получил следующую ошибку: if response.get('X-Frame-Options') is not None: AttributeError: 'NoneType' object has no attribute 'get' - person forest; 18.02.2021
comment
Потому что, если access_token не найден в cookie в то время, access_token вернет None. И наше условие не будет выполнено. поэтому метод __call__ не вернул никакого ответа. Я отредактировал свой ответ. - person Pradip; 18.02.2021
comment
Другой способ установить и получить файл cookie httponly. Проверьте это: stackoverflow.com/a/66248320/14131913) и посмотрите это stackoverflow.com/a/63622625/14131913 или github.com/HarryAustin/tweeter-DrfTest-httonlycookie/blob/main/ - person Pradip; 18.02.2021