在Django视图中,我正在创建一个用户提交表单或按钮的系统。之后,我的Django视图将请求发送到外部Python脚本,此脚本接收到该请求,检索有关该用户的一些数据,并将该数据作为响应发送给Django视图,该视图将对该数据执行一些操作(显示它等等),所有这些都是使用Python请求来完成的。因此,外部Python脚本的工作方式类似于微服务。

我能够发送请求,而且我还设法使我的视图接收到来自外部Python脚本的响应,我只在身份验证方面遇到问题。

这是我将数据发送到Django视图的方式:

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})


这就是这里发生的情况:发送带有某些凭据的请求,然后login视图对那些凭据进行身份验证,如果对凭据进行了身份验证,则数据由myTestView打印。

这是我的看法:

@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


该代码有效,唯一的问题是,应该使用该服务的用户名和密码代替USERNAME和PASSWORD。由于外部脚本发送有关user1的数据,因此只有user1可以读取该数据。

因此,如果user1使用该视图,则用户名应为user1,密码应为USER1PASS。如果该视图由user2使用,依此类推。

在实际阶段,要将数据发送给用户,我需要手动更改以下代码。相反,我需要一种将用户凭据发送给Django的方法,以下是其中涉及的代码段:

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


我不知道这个问题是否足够清楚。任何建议表示赞赏!

最佳答案

如果我对您的理解正确,那么您想保护“微服务外部Python脚本”。我对吗?

如果是“外部”,那么为什么要传递用户密码?这是同一个数据库吗?如果是这样,为什么这个微服务是外部的?这对我来说还不清楚:)

无论如何。首先,您无法获取用户密码作为可以发送到该外部脚本的加密文本。请参阅Django文档,密码如何存储:https://docs.djangoproject.com/en/3.0/topics/auth/passwords/#how-django-stores-passwords

如果您确实需要在外部服务器上运行此脚本,最好的解决方案(我认为)将是DRFTokenAuthentication

在您的外部脚本上,您还可以编写简单的中间件来检查请求的IP,并仅允许来自安全IP列表的请求

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


当然,在您的中间件类中添加您的类:

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


希望对您有所帮助,但如果没有,请告诉我。也许我只是需要更好地了解您的问题:)

关于python - 使用Python请求将数据传递到Django View ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59479538/

10-14 19:31
查看更多