简体   繁体   中英

How can i authenticate a POST request in Django?

I built a custom view where, when the page is loaded, the view sends a request to an external Python script. This script should retrieve some data of the user who sent the request and send it back as a response to the Django view, which will show it to the user.

The problem with my actual code is that i don't know how to authenticate the request sent from the external script to Django. In order for Django to accept the request and show the user their data, it needs to be authenticated with the user's crdeentials. The problem is that the external Python script doesn't have those credentials, unless the Django view sends it first.

So, X user is using the view, the view sends a request to the external script, the external script should send a response with the user's data and the credentials of user X . Same goes if user Y is using the view and so on.

Since this service is handling personal data, i would like it to be as safe as possible.

Here is what i have: This is how the request is sent from the external script to the Django view

import json

import requests

session = requests.session()
token = session.get('http://127.0.0.1:8000/loginview/')

session.post('http://127.0.0.1:8000/loginview/',
             data={
                 'username': '**'USER**',
                 'password': '**PASSWORD**',
                 'csrfmiddlewaretoken': token})

token = session.get('http://127.0.0.1:8000/myTestView/')
data = json.dumps({'test': 'value'})
session.post('http://127.0.0.1:8000/myTestView/',
             data={
                 'csrfmiddlewaretoken': token,
                 'data': data})

The whole problem is there on the fields USERNAME and PASSWORD. This external script is not able to get the credentials of the user who sent the request dynamically, unless i send them first with the first Django request.

Here is how the request is accepted:

@login_required
def myTestView(request):
    if request.method == 'POST':
        data = request.POST.get('data')
        print(json.loads(data))
        print('received.')

    response = HttpResponse(get_token(request))
    return response    

def login_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)

        if user is not None:
            login(request, user)
            return HttpResponse('authenticated')
        else:
            return HttpResponseForbidden('wrong username or password')

    response = HttpResponse(get_token(request))
    return response

So here login_view accepts the request and the other view does whatever i need to do with it.

Tl;Dr My Django service should send a request to an external script, the external script as a response sends something back to Django. Django needs to authenticate this request somehow; since the external script is separated from Django, there is no way for it to retrieve the credentials, unless i send them first.

If you don't want to add a different authentication mechanism (which would be more appropriate for an API, eg token authentication ), then the steps to do this are to replicate what your browser does.

(Tip: Look at the request and response headers in your browser debug tools during a normal login sequence)

  1. Fetch the login view to receive a CSRF cookie and the CSRF token.
  2. Send the POST request to the login view, including the CSRF cookie. The response will contain the session cookie which you should use for every subsequent request.
  3. Now you can POST to any other view, by including the session cookie.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM