본문 바로가기
부트캠프TIL, WIL/AI웹개발(스파르타코딩클럽)

[AI웹개발][53일차TIL] 포스트맨에서 CSRF토큰 인증에러, Serializer없이 Body에 JSON데이터를 입력할 때 생기는 서버500 오류

by 우지uz 2023. 5. 19.

 파이썬, 장고, DRF 복습 3일차

목차

1. redirect 함수에 대해서
2. template에서 url 불러오는 방법
3. CSRF 토큰 인증 에러
4. Django 의 Serializer를 쓰지 않고, FBV를 썼을 때 포스트맨에서 JSON데이터로 POST 했을 때에 오류
5. 코딩테스트 주사위 던지기
6. 후발대 강의

 

1. redirect 인자 

url 문자열이 꼬여버렸는지, 읽어오지 못하는 에러가 발생했다. 내가 혹시 

redirect 인자로 , url 문자열을 잘 못 입력했는지 ...?

from django.urls import path
from . import views

app_name = 'myapp'
urlpatterns = [
    path('detail/<int:pk>/', views.detail_view, name='detail'),
]

 

redirect 인자를 확인해본 결과 url string(문자열)도 가능, url pattern도 가능하다고 한다. 
위에서 url string(문자열)은 detail/<int:pk>/이고
url pattern은 name='detail'에 detail이다. 

views.py에 redirect 인자를 모두, URL pattern으로 바꿔주었다. 

def tweet(request):
    if request.method == 'GET':  # 요청하는 방식이 GET 방식인지 확인하기
        user = request.user.is_authenticated  # 사용자가 로그인이 되어 있는지 확인하기
        if user:  # 로그인 한 사용자라면3
            all_tweet = TweetModel.objects.all().order_by('-created_at')
            return render(request, 'tweet/home.html', {'tweet': all_tweet})
        else:  # 로그인이 되어 있지 않다면
            return redirect('sign-in')
    elif request.method == 'POST':  # 요청 방식이 POST 일때
        user = request.user  # 현재 로그인 한 사용자를 불러오기
        my_tweet = TweetModel()  # 글쓰기 모델 가져오기
        my_tweet.author = user  # 모델에 사용자 저장
        my_tweet.content = request.POST.get('my-content','')  # 모델에 글 저장
        my_tweet.save()
        return redirect('tweet')

템플릿에 폼 태그에도 url문자열을 연결해주었다. 

<form action="/tweet/" method="post">
    {% csrf_token %}
    <div class="form-group mb-2">
      <textarea class="form-control" style="resize: none" name="my-content" id="my-content"></textarea>
    </div>
    <button type="submit" class="btn btn-primary" style="float:right;">작성하기</button>
</form>

 

2. template 에서도 불러올 수 잇다. 
action="{% url 'post' %}"

추후에 수정하겠습니다! 

 

3. CSRF 토큰 인증 에러

DRF로 작업할때에는, 토큰 인증 에러에 대한 내용을 만나보지 못했는데

from django.shortcuts import render, redirect
from django.contrib.auth import get_user_model #사용자가 있는지 검사하는 함수
from user.models import UserModel
from django.contrib import auth
from django.http import HttpResponse


def sign_up_view(request):
    if request.method == 'GET':
        return render(request, 'user/signup.html')
    elif request.method == 'POST':
        username = request.POST.get('username', None)
        password = request.POST.get('password', None)
        password2 = request.POST.get('password2', None)
        bio = request.POST.get('bio', None)

        if password != password2:
            return render(request, 'user/signup.html')
        else:
            exist_user = get_user_model().objects.filter(username=username)
            if exist_user:
                return render(request, 'user/signup.html') # 사용자가 존재하기 때문에 사용자를 저장하지 않고 회원가입 페이지를 다시 띄움
            else:
                UserModel.objects.create_user(username=username, password=password, bio=bio)
                return redirect('sign-in') # 회원가입이 완료되었으므로 로그인 페이지로 이동
# 회원 가입시, 이미 존재하는 유저이다 > 회원 가입 할 필요 없음
# 이미 존하는 유저가 아니다 > 회원 가입 시켜야함
# user/views.py

def sign_in_view(request):
    if request.method == 'POST':
        username = request.POST.get('username', None)
        password = request.POST.get('password', None)

        me = auth.authenticate(request, username=username, password=password)  # 사용자 불러오기
        if me is not None:  # 저장된 사용자의 패스워드와 입력받은 패스워드 비교
            auth.login(request, me)
            return render(request, 'tweet/home.html')

        else:
            return redirect('sign-in')  # 로그인 실패
    elif request.method == 'GET':
        return render(request, 'user/signin.html')

퓨어 장고 및 FBView를 작성했을 때에 

template에 form태그 밑에 

<form action="/tweet/" method="post">
    {% csrf_token %}
    <div class="form-group mb-2">
      <textarea class="form-control" style="resize: none" name="my-content" id="my-content"></textarea>
    </div>
    <button type="submit" class="btn btn-primary" style="float:right;">작성하기</button>
</form>

{% csrf_token %}가 있는 것을 확인할 수 있는데 
일반적으로 post 메소드를 이용한,  폼 태그를 이용할때

csrf_token인증을 받아야 하는데 
이 인증 없이 폼 형식을 이용해서, 프론트 엔드에 있는 내용들을 서버로 전송시키면

CSRF token 에러가 떠버렸다. 

해결하기 위한 방법으로 다음 블로그를 추천하는데, 같은 내용이라
이 글을 보고 하셔도 된다. (https://hayeon1549.tistory.com/35)

PostMan을 이용할 때 이 에러가 떴기 때문에, 해결 방법 및 도구도 포스트맨이고

다음과 같이 Headers 와 Tests를 작성하면 된다. 

var xsrfCookie = postman.getResponseCookie("csrftoken");
postman.setGlobalVariable('csrftoken', xsrfCookie.value);

Value값은, python manage.py createsuperuser
해서 superuser로 로그인을 포스트맨에서 하게 되면, 

CSRFToken Value가 나오는데, 그걸 입력하면 된다. 

 

 

4. Django 의 Serializer를 쓰지 않고,
FBV를 썼을 때 포스트맨에서 JSON데이터로 POST 했을 때에 오류

여기서 핵심적인 원인은, Serializer를 사용하지 않았는데
JSON 데이터로 Body를 보냈다는 사실이다. 

그래서 서버에서는 첫번째 인자인 username을 request로 부터 받아오지 못했기 때문에
500 Server Error가 나왔고 

ValueError가 나왔다는 사실이 이해가 됐다. 

Body 에서 raw - JSON 데이터를, form-data로 바꿔서
다음과 같이 회원가입 시 필요한 Raw들을 입력하면 된다. 

로그인을 성공했다는 것을 확인할 수 있습니다. 

 

5. 코딩테스트 주사위 던지기

https://school.programmers.co.kr/learn/courses/30/lessons/181916

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

6. 후발대 강의

1. 다양한 외래키와 활용법, 역참조에 대한 이해 

2. Serializer 실행 순서

3. 데이터베이스 마이그레이션에 대해서 들었습니다. 

(데이터 베이스 마이그레이션은 시간이 없어서 생략하신걸로 ...총총)