개발/Python

localhost (python 요청)에 연결하려고 할 때 CSRF와 관련된 403 오류 발생

MinorMan 2020. 10. 2. 02:14
반응형
C:\Anaconda3\envs\YYcompany\lib\site-packages\pymysql\cursors.py:329: Warning: (1265, "Data truncated for column 'original_url' at row 1") self._do_get_result()

<질문>

Python의 요청 라이브러리를 사용하여 Django 뷰 중 하나에 대한 연결을 테스트하려고합니다. POST 요청을 시도 할 때 request.text를 볼 때 CSRF 확인에 실패했으며 양식을 제출할 때 CSRF 토큰이 필요하다는 정보를받습니다. 나는 여기에서 더 많은 연구를했고 이것으로 최선을 다했습니다.

이것은 지금 내 코드입니다.

post_request = requests.session()
post_request.get('http://127.0.0.1:8000/message/')
csrftoken = post_request.cookies['csrftoken']

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'}
final_request = post_request.post('http://127.0.0.1:8000/message/', headers=dict(Referer=post_request))

이것이 내 견해입니다.

def add_message(request):
    form = InputInfoForm(request.POST)

    if request.method == 'POST':
        return HttpResponse('hey')

    return HttpResponse('test')

그렇다면 요청을 사용하여 뷰에서 CSRF 토큰을 어떻게 확인합니까?


<답변1>

코드의 문제는 다음과 같습니다. Django는 쿠키에 CSRFTOKEN이있을 것으로 예상하지만, 게시 매개 변수에도 csrfmiddlewaretoken이라는 이름으로 게시 데이터를 제공해야합니다. 그래서 파이썬 요청 메소드를 사용하여

post_request = requests.session()
post_request.get('http://127.0.0.1:8000/message/')
csrftoken = post_request.cookies['csrftoken']
#now the csrftoken cookie is stored in csrftoken
final_request = post_request.post('http://127.0.0.1:8000/message/', data = {'csrfmiddlewaretoken' : csrftoken}, cookies=post_request.cookies) #assuming the post data for your form is empty, else add in the 'data' dictionary. just check your 'InputInfoForm' form for any fields. 
final_request.text  #will read you the data returned from the view, in your case "hey"

보기에서 다음과 같이 변경하십시오.

from django.shortcuts import render  #needed
def add_message(request):
    form = InputInfoForm(request.POST)

    if request.method == 'POST':
        return HttpResponse('hey')

    return render(request, 'test.html')  #assuming no context...

앱 폴더에 'templates'폴더를 추가하고 템플릿 안에 'test.html'파일을 만듭니다. 그런 다음 다음을 추가하십시오.

{%csrf_token%}

그런 다음 프로젝트 폴더의 urls.py 안에

from django.conf.urls import url, include
urlpatterns = [
#admin_page --snip--
url(r'^message/', include('APPNAME.urls', namespace='message')),
]

그런 다음 앱 폴더 안에 'urls.py'파일을 만들고 다음을 추가하십시오 ...

from .views import add_message #your view
from django.conf.urls import url

app_name = "APP_NAME"  #from django2.0 on wards 
urlpatterns = [
    url(r'^$', add_message, name='test'), 
] 

그럼 당신은 갈 수 있습니다. 위와 같이 파이썬 코드를 실행하여 확인하십시오.


<답변2>

POST 데이터에 CSRF 토큰을 보내야합니다.

r = post_request.post(
    'http://127.0.0.1:8000/message/', 
    data={'csrfmiddlewaretoken': csrftoken},
    headers=dict(Referer=URL)
)

CSRF 토큰을 보내는 다른 방법은 헤더를 사용하는 것입니다.

r = post_request.post(
    'http://127.0.0.1:8000/message/', 
    headers={'Referer': URL, 'X-CSRFToken': csrftoken)
)

HTTP_X_CSRFTOKEN은 설정의 기본값입니다.

반응형