Django 发送 POST 请求时返回 403 错误

发布于 2024-11-25 20:07:36 字数 483 浏览 1 评论 0原文

当我使用以下 Python 代码向我的 Django 网站发送 POST 请求时,出现 403: Forbidden 错误。

url = 'http://www.sub.example.com/'
values = { 'var': 'test' }

try:
    data = urllib.urlencode(values, doseq=True)
    req = urllib2.Request(url, data)
    response = urllib2.urlopen(req)
    the_page = response.read()
except:
    the_page = sys.exc_info()
    raise

当我打开任何其他网站时,它都可以正常工作。 example.com 也是 Django 网站,并且也可以正常工作。 我想,这是 Django 配置问题,谁能告诉我我应该做什么来提供对我的脚本的访问?

when I'm using following Python code to send a POST request to my Django website I'm getting 403: Forbidden error.

url = 'http://www.sub.example.com/'
values = { 'var': 'test' }

try:
    data = urllib.urlencode(values, doseq=True)
    req = urllib2.Request(url, data)
    response = urllib2.urlopen(req)
    the_page = response.read()
except:
    the_page = sys.exc_info()
    raise

When I'm opening any other website it works properly.
example.com is Django website too, and it works properly too.
I think, that's Django config problem, can anyone tell me what should I do to provide access to my script?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

玻璃人 2024-12-02 20:07:37

响应是 403,因为 django 在您发出的每个 POST 请求中都需要 csrf 令牌(包含在 post 数据中)。

有多种方法可以做到这一点,例如:

从 cookie 获取令牌,该方法已在文章中进行了解释,在此处输入链接描述

,或者

您可以使用模板中提供的 {{ csrf_token }} 从 DOM 访问它

所以现在使用第二个方法:

var post_data = {
  ...
  'csrfmiddlewaretoken':"{{ csrf_token }}"
  ...
}

$.ajax({
  url:'url',
  type:'POST'
  data:post_data,
  success:function(data){
    console.log(data);
  },
  error:function(error){
    console.log(error);
  }
});

The response is 403 because django requires a csrf token (included in the post data) in every POST request you make.

There are various ways to do this such as:

Acquiring the token from cookie and the method has been explained in article enter link description here

or

You can access it from DOM using {{ csrf_token }}, available in the template

So now using the second method:

var post_data = {
  ...
  'csrfmiddlewaretoken':"{{ csrf_token }}"
  ...
}

$.ajax({
  url:'url',
  type:'POST'
  data:post_data,
  success:function(data){
    console.log(data);
  },
  error:function(error){
    console.log(error);
  }
});
挖个坑埋了你 2024-12-02 20:07:37

或者您可以允许发出此帖子请求的权限。

注意:应该在您不需要验证用户在我们的服务器上发布任何内容的情况下使用,例如,当新用户第一次注册时

from rest_framework.permissions import AllowAny

class CreateUser(APIView):
    permission_classes = (AllowAny,)
    def post(self, request, format=None):
        return(Response("hi"))

进一步请注意,如果您想从不同的域发出该 post 请求(如果应用程序的前端在 React 或 Angular 中,后端在 Django 中),请确保在设置文件中添加以下内容:

  1. 更新 INSTALLED_APPS 以使用“coreHeaders”:

    已安装的应用程序 = [
    'corsheaders',
    ]

  2. 通过再次将以下内容添加到设置文件来将您的前端域列入白名单:

    CORS_ORIGIN_WHITELIST = (
    '本地主机:8080',
    )

Or you can allow the permission to make this post request.

Note: Should be used in the cases where you don't need to authenticate the users for posting anything on our server, say, when a new user registers for the first time.

from rest_framework.permissions import AllowAny

class CreateUser(APIView):
    permission_classes = (AllowAny,)
    def post(self, request, format=None):
        return(Response("hi"))

Further Note that, If you want to make that post request form a different domain (in case when the front of the application is in React or angular and the backend is in Django), make sure the add following in the settings file:

  1. Update the INSTALLED_APPS to use 'coreHeaders' :

    INSTALLED_APPS = [
    'corsheaders',
    ]

  2. White list your front end domain by adding following to settings file again:

    CORS_ORIGIN_WHITELIST = (
    'localhost:8080',
    )

記柔刀 2024-12-02 20:07:37

Django 文档提供了多种方法来确保包含 CSRF 令牌。请参阅 https://docs.djangoproject.com/en/1.11/ref/csrf/ 了解详细信息。

Django documentation provides several ways to ensure that CSRF tokens are included. See https://docs.djangoproject.com/en/1.11/ref/csrf/ for details.

橘虞初梦 2024-12-02 20:07:37

当身份验证令牌过期或没有随请求发送令牌时,我收到此错误。使用更新的令牌解决了问题。

curl -X POST -H "Authorization: Token mytoken" -d "name=myname&age=0" 127.0.0.1:8000/myapi/

curl -X POST -H "Authorization: JWT mytoken" -d "name=myname&age=0" 127.0.0.1:8000/myapi/

取决于令牌类型。

I got this error when an authentication Token was expired or when no Token was sent with the request. Using a renewed token fixed the problem.

curl -X POST -H "Authorization: Token mytoken" -d "name=myname&age=0" 127.0.0.1:8000/myapi/

or

curl -X POST -H "Authorization: JWT mytoken" -d "name=myname&age=0" 127.0.0.1:8000/myapi/

depending on Token type.

风启觞 2024-12-02 20:07:37

我也遇到了这个问题,因为我尝试使用 '../url' URL 跳转从另一个端点访问主端点。
我的解决方案是为同一视图集添加另一条路径;

router.register('main/url',ViewSet,'name');
router.register('secondary/url',ViewSet,'name')

但在您的情况下,您正尝试从完全不同的位置访问它,从 Django 的角度来看,因此您需要使用 @crsf_exempt 中间件标记您的 ViewSet,这将禁用与 CRSF 相关的安全协议。

I too had this problem, because I Tried to access the Main endpoint from another endpoint using '../url' URL Jumping.
My Solution was to add another path for the same viewset;

router.register('main/url',ViewSet,'name');
router.register('secondary/url',ViewSet,'name')

But in Your Case You are Trying to access it from a completely different Location, From Django's Point of view So You need to mark you ViewSet with @crsf_exempt middleware which will Disable Security Protocols Related to CRSF.

单调的奢华 2024-12-02 20:07:36

看这里 https://docs.djangoproject.com/en/dev/ref /csrf/#如何使用它

尝试使用 @csrf_exempt 标记您的视图。这样,Django 的 CSRF 中间件将忽略 CSRF 保护。您还需要使用 from django.views.decorators.csrf import csrf_exempt。请参阅:https://docs.djangoproject.com/en/dev/ref/csrf/#utilities< /a>

请注意,在您的视图中禁用 CSRF 保护就等于为 CSRF 攻击打开了大门。

如果安全性对您至关重要,请考虑使用 @csrf_exempt 后跟 @requires_csrf_token (请参阅:https://docs.djangoproject.com/en/dev/ref /csrf/#unprotected-view-needs-the-csrf-token)。然后,在您的脚本中传递此令牌即可。

Look here https://docs.djangoproject.com/en/dev/ref/csrf/#how-to-use-it.

Try marking your view with @csrf_exempt. That way, Django's CSRF middleware will ignore CSRF protection. You'll also need to use from django.views.decorators.csrf import csrf_exempt. See: https://docs.djangoproject.com/en/dev/ref/csrf/#utilities

Please be advised that by disabling CSRF protection on your view, you are opening a gate for CSRF attacks.

If security is vital to you then consider using @csrf_exempt followed by @requires_csrf_token (see: https://docs.djangoproject.com/en/dev/ref/csrf/#unprotected-view-needs-the-csrf-token). Then, in your script pass this token and that's it.

聚集的泪 2024-12-02 20:07:36

您发布的视图上有 Django 表单吗?如果是这样,我想知道它是否给出了 csrf 错误。我认为这表现为 403。在这种情况下,您需要添加 {{ csrf_token }} 标签。只是一个想法。

Does the view that you are posting to have a Django Form on it? If so, I wonder if it's giving a csrf error. I think that manifests itself as a 403. In that case, you'd need to add the {{ csrf_token }} tag. Just a thought.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文