2017-10-29 8 views
1

django를 백엔드 용 웹 API로 사용하고 React JS를 프론트 엔드 용 웹 UI로 사용하고 있습니다. 사용자는 사용자 정보로 등록하기 위해 django에 POST 요청을 보낼 웹 UI에서 등록합니다. CSRF를 통한 가입보기를 보호하고 싶습니다. 그러므로 나는 아래의 단계들로 나옵니다.CRSF 토큰의 Django 버그

먼저 가입 페이지가로드되면 더미 코드 GET을 실행하여 아래 코드와 함께 csrf 토큰을 저장하도록 요청합니다.

handleSend(){ 
    let req = { 
    url: 'http://localhost:9000/vcubes/retrieve_token/', 
    method : 'GET', 
    withCredentials: true 
    } 
    axios(req) 
} 

그런 다음 사용자가 가입 양식을 제출하면 다른 POST 요청이 실행됩니다. 위의 코드

const data = JSON.stringify({ 
     'first_name': this.state.first_name, 
     'last_name': this.state.last_name, 
     'email': this.state.email, 
     'contact_number': this.state.contact_number, 
     'password1': this.state.password1, 
     'password2': this.state.password2, 
     }) 
     let req = { 
     url: 'http://localhost:9000/vcubes/signup/', 
     method : 'POST', 
     headers: { 
       'Content-Type': 'text/plain' 
     }, 
     data: data 
     } 
     axios.defaults.headers.common['X-CSRF-TOKEN'] = this.getCookie('vcubes') 

는 [옵션 먼저 다음 장고는 200 OK 다시 보내면, 그 실제 POST 요청이 트리거 될 장고 전송한다.

enter image description here enter image description here

서프라이즈! Django는 CSRF 쿠키를 설정하지 않는다고 말했습니다.

Forbidden (CSRF cookie not set.): /vcubes/signup/ 
[30/Oct/2017 01:30:48] "POST /vcubes/signup/ HTTP/1.1" 403 2857 

settings.py은 다음과 같습니다. 나는 구글과 유래에서 문제를 찾을 수 있지만, 거의 어떤 도움을 얻을하는 하루를 보내고있다 views.py

@ensure_csrf_cookie 
def retrieve_token(request): 
    return HttpResponse(status=200) 

def signup(request): 
    print request.META 
    form = UserCreationForm(json.loads(request.body)) 
    # user = form.save(commit=False) 
    # user.is_active = False 
    # user.save() 
    # 
    # mail_subject = 'Activate your account.' 
    # message = render_to_string('acc_active_email.html', { 
    #  'name': user.get_full_name(), 
    #  'domain': 'localhost:9000', 
    #  'uid': urlsafe_base64_encode(force_bytes(user.pk)), 
    #  'token': account_activation_token.make_token(user), 
    # }) 
    # to_email = user 
    # email = EmailMessage(
    #  mail_subject, message, to=[to_email] 
    #) 
    # email.send() 
    return HttpResponse(status=200) 

에서

INSTALLED_APPS = [ 
    'django.contrib.admin', 
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    'corsheaders', 
    'django.contrib.messages', 
    'django.contrib.staticfiles', 
    'rest_framework', 
    'custom_user', 
    'vcubes', 
] 

MIDDLEWARE = [ 
    'django.middleware.security.SecurityMiddleware', 
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'corsheaders.middleware.CorsMiddleware', 
    'django.middleware.common.CommonMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.messages.middleware.MessageMiddleware', 
    'django.middleware.clickjacking.XFrameOptionsMiddleware', 
] 

CSRF_TRUSTED_ORIGINS = (
    'localhost:8000', 
    '127.0.0.1:8000' 
) 

CSRF_COOKIE_NAME = 'vcubes' 

CSRF_HEADER_NAME = 'HTTP_X_CSRF_TOKEN' 

CORS_ORIGIN_ALLOW_ALL = True 

CORS_ALLOW_CREDENTIALS = True 

CORS_ORIGIN_WHITELIST = (
    'localhost:8000', 
    '127.0.0.1:8000' 
) 


CORS_ALLOW_HEADERS = (
    'access-control-allow-credentials', 
    'access-control-allow-origin', 
    'access-control-request-method', 
    'access-control-request-headers', 
    'accept', 
    'accept-encoding', 
    'accept-language', 
    'authorization', 
    'connection', 
    'content-type', 
    'dnt', 
    'credentials', 
    'host', 
    'origin', 
    'user-agent', 
    'X-CSRF-TOKEN', 
    'X-CSRFToken', 
    'x-requested-with', 
) 

을 (난 단지 CORS 및 CSRF 일부 관련 코드를 보여줍니다) . 제발 저를 계몽하십시오!

+0

도'CSRF_COOKIE_SECURE'도 설정되어 있습니까? – scharette

+0

그리고이 게시물을 보지 못했다면 많은 수정 사항이 있습니다. [this] (https://stackoverflow.com/questions/17716624/django-csrf-cookie-not-set) – scharette

+0

CSRF_COOKIE_SECURE가 설정되어 있습니다. 기본적으로 false입니다. 내 경우에는 괜찮습니다. –

답변

0

게시 요청에 withCredentials: true이 누락되었습니다. 즉, 요청과 함께 CSRF 쿠키가 전송되지 않습니다.

+0

작동합니다! 왜 나는 withCredentials를 보내야 만 하는가? 사실은'axios.defaults.headers.common [ 'X-CSRF-TOKEN'] = this.getCookie ('vcubes')'와 맞습니까? 이후 코드가 없으면 요청 헤더에 여전히 '쿠키 : vcubes = 3HqESj1ea9Pw6gAah6CvlGOlvUDYURW1MBbwsXYpzIJWvXT6Sjiylpf2hDlSZgLh'가 있습니다. –

+0

CSRF 보호는 항상 토큰을 쿠키로 보내야합니다. 또한 요청 본문이나 헤더로 토큰을 보내야합니다. – Alasdair