4

基本的なログインとログアウトのページを設計するために django を使用しています。以下は私のコードです

設定.py

TEMPLATE_CONTEXT_PROCESSORS = (
    ...........
    ...........
    "django.contrib.messages.context_processors.messages",
    "django.core.context_processors.request",
    "django.core.context_processors.csrf",
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)
INSTALLED_APPS = (
    'django.contrib.auth',
    .......
    ....... 
)

urls.py

from django.conf.urls.defaults import *
from django.conf import settings

urlpatterns = patterns('',
             url(r'^$', 'learn_django.views.home_page'),          
             url(r'^login/$', 'learn_django.views.login'),
             url(r'^logged_in$', 'learn_django.views.logged_in'),
             url(r'^logout/$', 'learn_django.views.logout'),
)


if settings.DEBUG:
    urlpatterns = patterns('',
    url(r'^media/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
) + urlpatterns

ビュー.py

from django.shortcuts import render_to_response
from django.template import RequestContext

def home_page(request):
    return render_to_response("home_page.html")

def login(request):
    return render_to_response("login.html")

def logged_in(request):
    return render_to_response("logged_in.html",context_instance=RequestContext(request))

base.html

{% load staticfiles %}
<html xmlns="http://www.w3.org/1999/xhtml"> 
  <head>
    <link rel="stylesheet" href="{% static 'css/home_remaining.css' %}" type="text/css">
    <title>{% block title %}{% endblock %}</title>
  </head>
  <body>
   <header>
     <div class='header_div'>
       <div class="logout"><p id='logout'><a href="/logout" >Logout</a></p><div>
       <div class="login"><p id='login'> <a href="/login" >Login</a></p><div>
     </div>
   </header>
   <div class="body_content">
      {% block body %}{% endblock %}
   </div>
</body> 
</html>

login.html

{% extends 'base.html' %}
{% block title %}Login Page{% endblock %}
{% block body %}
  <div id='container'>
      <form action="/logged_in" method="POST">
         {% csrf_token %}
            <label for="name">Username:</label><input type="name">
            <label for="username">Password:</label><input type="password">
            <div id="lower">
                <input type="submit" value="Login">
            </div>
      </form> 
   </div>     
{% endblock %}

上記は、でLogin指定されたリンクをクリックしたときにログインフォームを表示する完全なコードですbase.html

ログインが表示され、いくつか入力しusername、ボタンpasswordをクリックした後Login、 を示すエラー ページcsrf errorが表示されました。

多くのことをグーグルで検索し{% csrf_token %}、フォームタグ内に追加django.core.context_processors.csrfし、テンプレートコンテキストプロセスにも追加しましたsettings.py

以下は、次のようなエラーメッセージです

Forbidden (403)
CSRF verification failed. Request aborted.
Help
Reason given for failure:
    CSRF cookie not set.

In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
Your browser is accepting cookies.
The view function uses RequestContext for the template, instead of Context.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
You're seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.
You can customize this page using the CSRF_FAILURE_VIEW setting.

したがって、テンプレートコンテキストプロセスから django.core.context_processors.csrf を削除すると、正常に動作します。しかし、csrf保護も使用したいです。

最後に、実際に上記のビュー コードで何が問題なのか、csrf エラー ページが表示される理由と上記のエラー ページを回避する方法を教えてください。

views.py関数にコードを追加する必要があるかどうか

コードを実際に理解するのに役立つように、上記の関数に基本的なログインおよびログアウト機能コードを追加してください......

編集済み

上記の問題について、以下のような csrf_exempt 関数をインポートしました

from django.views.decorators.csrf import csrf_exempt

これをビューの前にデコレータとして指定すると、logged_inログインボタンをクリックしたときにエラーページが表示されませんでした

しかし、テンプレートから Requestcontext を送信するなどの以下の方法が機能しない理由はまだ疑問に思っています

4

1 に答える 1

6

関数にを渡す必要がありRequestContextますrender_to_response

def home_page(request):
    return render_to_response("home_page.html", context_instance=RequestContext(request))

それか、の受け渡しを処理する新しいレンダリング関数を使用しRequestContextてください。

def home_page(request):
    return render(request, "home_page.html")

RequestContextは、テンプレートに渡されるコンテキストディクショナリにさまざまな便利なものを追加します。これには、csrfトークンが含まれます。詳細については、RequestContextのドキュメントをご覧ください。

あなたの場合、loginビューはlogin.htmlテンプレートをレンダリングしていますが、csrfトークンを渡していません。login.htmlテンプレートがサーバーに(に)/logged_inポストバックすると、logged_inビューはそのcsrfトークンをチェックします。それはありません(あなたがそれを含めなかったので)。したがって、クロスサイトリクエストフォージェリを受信したと想定します。

プロセスをより理解するために、 csrfドキュメントを読んでください。

于 2013-03-01T07:08:50.163 に答える