简体   繁体   中英

Passing data to Django view using Python requests

In my Django view, i'm creating a system where an user submits a form or a button. After that, my Django view sends a request to an external Python script, this script receives the request, retrieves some data about that user and sends this data as a response to the Django view, which will perform some operations with this data (show it to the user and so on), all of that is made using Python-Requests. So the external Python script works like a microservice.

I'm able to send the request, and i also managed to make my view receive the response from the external Python script, i only have a problem with authentication.

Here is how i send data 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})

This is what happens here: a request with some credentials is sent, then the login view authenticates those credentials, if the credentials are authenticated, the data is printed by myTestView .

Here are my views:

@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

This code works, the only problem is that instead of USERNAME and PASSWORD there should be the username and the password of the user who is using the service. Since the external script sends data about user1 , only user1 should read that data.

So if user1 is using the view, the username should be user1 and the password should be USER1PASS . Same if the view is used by user2 and so on.

At the actual stage, to send data to an user i need to change the following code manually. Instead, i need a way to send to Django the user's credentials, here is the snippet involved:

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

I don't know if the question was clear enough. Any advice is appreciated!

If I understand you correctly, you want to secure your "microservice external Python script". Am I right?

If it's "external", then why you want to pass user's password? Is this the same database? If it is so why this microservice is external? This is not clear for me :)

Anyway. First of all, you cannot get user's password as an encrypted text that could be send to that external script. See Django documentation how passwords are stored: https://docs.djangoproject.com/en/3.0/topics/auth/passwords/#how-django-stores-passwords

If you really need to run this script on external server, best solution (n my opinion) for you will be DRF with TokenAuthentication .

On your external script you can also write simple middleware to check request's IP and allow only requests from secure IP list

ALLOWED_IP = [allowed_ip_list]

class CheckRequestsIP(object):
   def process_request(self, request):
      ip_to_check = request.META['REMOTE_ADDR']
      if ip_to_check in ALLOWED_IP:
          response = ... # Do your code and prepare response
          return response
      return None

And of course in your middleware classes add your class:

MIDDLEWARE_CLASSES = (
   ...
   'path.to.my.CheckRequestsIP',
   ...
)

Hope it helps, but if not please let me know. Maybe I just need to better understand your problem :)

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