request.POST возвращает старые значения после их обновления в пользовательском промежуточном программном обеспечении — django 1.11.9

Я использую Джанго 1.11.9.

Я хочу добавить client_id и client_secret в запрос POST django.

Вот как выглядит мой файл middleware.py:

class LoginMiddleware(object):

def __init__(self, get_response):
    self.get_response = get_response
    # One-time configuration and initialization.

def __call__(self, request):
    # auth_header = get_authorization_header(request)
    # Code to be executed for each request before
    # the view (and later middleware) are called.
    #Add Django authentication app client data to the request
    request.POST = request.POST.copy()
    request.POST['client_id'] = '12345678'
    request.POST['client_secret'] = '12345678'
    response = self.get_response(request)

    # Code to be executed for each request/response after
    # the view is called.

    return response

Промежуточное ПО успешно обрабатывается, когда я проверяю его с помощью отладчика. Думал, когда представление называется, поля «client_id» и «client_secret» отсутствуют в запросе.

После некоторых экспериментов я понял, что запрос не обновляется, и когда он вызывается в другом представлении, он возвращает старые значения.

Позже я использую запрос в rest_framework_social_oauth2. И это тот момент, когда «client_id» и «client_secret» исчезают.

class ConvertTokenView(CsrfExemptMixin, OAuthLibMixin, APIView):
"""
Implements an endpoint to convert a provider token to an access token

The endpoint is used in the following flows:

* Authorization code
* Client credentials
"""
server_class = SocialTokenServer
validator_class = oauth2_settings.OAUTH2_VALIDATOR_CLASS
oauthlib_backend_class = KeepRequestCore
permission_classes = (permissions.AllowAny,)

def post(self, request, *args, **kwargs):
    import pdb ; pdb.set_trace()
    # Use the rest framework `.data` to fake the post body of the django request.
    request._request.POST = request._request.POST.copy()
    for key, value in request.data.items():
        request._request.POST[key] = value

    url, headers, body, status = self.create_token_response(request._request)
    response = Response(data=json.loads(body), status=status)

    for k, v in headers.items():
        response[k] = v
    return response

Мне нужно добавить client_id и client_secret в тело запроса, чтобы позже его можно было использовать rest_framework_social_oauth2.

В чем может быть проблема? Как правильно обновить запрос?


person Vadim Vzorov    schedule 13.01.2018    source источник


Ответы (1)


Поскольку вы работаете с request и обрабатываете запрос, вам необходимо реализовать метод process_request, поэтому результат будет примерно таким:

class LoginMiddleware(object):
    def process_request(self, request):
        request.session['client_id'] = '12345678'

а затем, на ваш взгляд:

def your_view(request):
    client_id = request.session['client_id']
person dmitryro    schedule 13.01.2018
comment
Я попытался добавить его и, похоже, не работает. Функции init и call должны оставаться правильными? В противном случае я получаю сообщение об ошибке: TypeError: object() не принимает параметров. Я также попытался поставить import pdb ; pdb.set_trace() в функции process_request, и я вижу, что эта функция не запускается. - person Vadim Vzorov; 14.01.2018
comment
Я также добавил некоторую дополнительную информацию в свой вопрос, чтобы дать более полное представление о проблеме, которую я пытаюсь решить. Может есть другие обходные пути? - person Vadim Vzorov; 14.01.2018
comment
Вы можете попробовать установить его (в process_request) в сеанс в request.session['client_id'] = '12345678', а затем, на ваш взгляд, получить его из request.session. __init__ и __call__ являются необязательными и используются, если вам нужно предварительно установить некоторые значения или изменить способ создания объекта, что вам не подходит. - person dmitryro; 14.01.2018
comment
request.session работает и доступен в другом представлении. Хотя для меня это не идеальное решение. Я использую пакет rest_framework_social_oauth2 и не хочу вносить изменения в его представления. Поэтому в идеале мне нужно обновить request.POST и точно передать обновленные данные. - person Vadim Vzorov; 14.01.2018
comment
Вы также можете попробовать установить request.POST = q_data, как здесь gist.github.com/LucasRoesler/700d281d528ecb7895c0, где q_data словарь ценностей. Так или иначе запрос на оркестрацию происходит в одном и том же методе. - person dmitryro; 14.01.2018
comment
Все вышеперечисленные методы помогают добавить информацию в объект запроса. Хотя, когда я перехожу к другому виду, вся эта информация теряется. Например. в моем промежуточном программном обеспечении.py request.POST = {'grant_type': ['convert_token'], 'backend': ['facebook'], 'token': ['1234'], 'client_id' = ['123'], 'client_secret' = ['123']}. Когда запрос вызывается впоследствии в представлении стороннего пакета, client_id и client_secret отсутствуют. Похоже, что используется старый словарь request.POST. Не уверен, как это возможно, но нужно будет найти другой обходной путь - person Vadim Vzorov; 14.01.2018