繁体   English   中英

Django 服务器 403(CSRF 令牌丢失或不正确)

[英]Django server 403 (CSRF token missing or incorrect)

我有一个带有 python 命令行客户端的基本 Django 服务器,用于发布到此服务。 我有一个登录功能和一个发布功能。 即使 CSRF 的 cookie 是从登录功能设置的,但当我在登录后尝试访问 post_product 端点时,服务器说禁止。

几天来我一直在解决这个问题,但没有任何运气。

/api/登录/ 功能:

from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponse

@csrf_exempt
def handle_login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(request, username=username, password=password)

        if user is not None:
            if user.is_active:
                login(request, user)
                if user.is_authenticated:
                    return HttpResponse(author.name + ' is logged in, Welcome!', status=201, content_type='text/plain')
                return HttpResponse(data)

            else:
                return HttpResponse('disabled account', status=400, content_type='text/plain')

        else:
            return HttpResponse('invalid login', status=400, content_type='text/plain')

    else:
        return HttpResponse('request method invalid ' + request.method, status=400, content_type='text/plain')


/api/postproduct/ 功能:

def post_story(request):
    if request.method == 'POST' and request.user.is_authenticated:
        # Pull product details from request.
        # Validate product details.
        # Create model and save.

Python终端客户端

FAILURE_MESSAGE = "The server responded with an unsuccessful code: "


def run():
    url ='http://127.0.0.1:8000' # For debugging
    logged_in = false
    with requests.session() as session:
        while True:
            command = input("""Enter one of the following commands:
            login 
            post \n""")

            # login case.
            if command == "login":
                url = user_inputs[1]
                logged_in = login(session, url)
                continue

            # post case.
            elif command == "post" and logged_in:

                post(session, url)                    
                continue

            else:
                print('incorrect command')
                continue


def login(session, url):
    username = input("Enter your username: \n")
    password = input("Enter your password: \n")
    response = session.post(url + "/api/login/", data={'username': username, 'password': password})

    # If any response but success notify user.
    if response.status_code != 201:
        print(FAILURE_MESSAGE + str(response.status_code))
        return False
    else:
        print("Successfully logged in!")
        return True


def post(session, url):
    # Check session is authenticated
    if 'csrftoken' not in session.cookies:
        print("Not authenticated, have you logged in to a service?")
        return

    # Omitted : prompt user for productname, category, price and details.

data = {'productname': productname, 'category': category, 'price': price, 'details': details}
    data_json = json.dumps(data)
    payload = {'json_payload': data_json}
    if not session_is_active():
        print("You aren't logged into any services")
        return
    else:
        response = session.post(url + "/api/postproduct/", data=payload)
        print(6)
        if response.status_code != 201:
            print(FAILURE_MESSAGE + str(response.status_code))
            return
        print("Post was successful")

当我运行客户端时,登录工作正常,并且在检查时确实设置了 csrf cookie。 但是,当我尝试发布时,服务器会以 403 forbidden 响应。 从服务器的输出:

[15/Aug/2019 15:45:23] "POST /api/login/ HTTP/1.1" 201 42
Forbidden (CSRF token missing or incorrect.): /api/postproduct/

Django 的 CSRF 保护要求您发布 CSRF cookie 和隐藏在表单字段中的令牌。 对于 AJAX 请求,您可以设置标题而不是表单字段。

尝试类似以下内容(未经测试):

headers = {'X-CSRFToken': session.cookies['csrftoken']}
response = session.post(url + "/api/postproduct/", data=payload, headers=headers)

向 Django 后端提交请求时,错误 = csrf Forbidden(CSRF 令牌丢失或不正确。):

在一个表单中,包含{% csrf_token %} ,它会生成一个带有 csrf 令牌值的输入标签,并且在请求中,头部包含 'X-CSRFTOKEN

headers: {
                content_type: 'application/json',
                'X-CSRFToken': "{{ csrf_token }}"
            },

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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