0

我编写了一个小的独立 python 脚本,它调用我基于 django 的后端,并且在登录和调用需要身份验证等的视图时一切正常。

一点代码

def dostuff():
    session = login(username, password)
    license = add_license(session)

def _helper(self, url, cookie=None):
    http = httplib2.Http()
    if cookie:
        headers = { "Cookie" : cookie }
    else:
        headers = {}
    response, content = http.request(host + url, "GET", headers=headers, body="")
    return response, content

def login(self, username, password):
    url = "/license/login?username=%s&password=%s" % (username, password)
    response, content = self._helper(url)
    sessioncookie = response["set-cookie"]
    customer_id = re.search("id=(?P<id>\d+)", content)
    if response["status"] == "200":
        return sessioncookie, customer_id.group("id")

def add_license(self, session):
    cookie = session[0]
    customer_id = int(session[1])-1
    url = "/license/add_license?customer_id=%s" % customer_id
    response, content = self._helper(url, cookie)
    content = content[1:-1]
    if response["status"] == "200": #ok
        data = json.loads(content)
        return data["fields"]

如果我将“GET”更改为“POST”,我会遇到 Django CSRF 错误页面(CSRF 验证失败)作为回报。如何将 POST 数据发送到 Django?

我在 Django 中的登录视图,我需要做任何特别的事情来添加 csrf 令牌吗?我的计划是在一切正常后重写它以发送 json。

 def my_login(request):
    done, username = get_input(request, "username")
    if not done:
        return username
    done, password = get_input(request, "password")
    if not done:
        return password
    user = authenticate(username=username, password=password)
    if user is not None:
       if user.is_active:
            login(request, user)
            return HttpResponse("Done, id=%s" % user.pk)
        else:
            return HttpResponse("User disabled")
    else:
        return HttpResponse("Invalid login")
4

3 回答 3

1

我让它工作了,我就是这样做的。就像 toto_tico 所建议的那样,我写了一个虚拟视图,我检索了 GET 来获取 CSRF 令牌。起初它没有通过 GET 发送 csrf 令牌,所以我不得不添加装饰器 ensure_csrf_cookie。

@ensure_csrf_cookie
def dummy(request):
    return HttpResponse("done")

然后我正常处理登录请求。

def my_login(request):
    ...handle login...

事实证明,仅将 cookie 添加到 POST 是不够的,我还必须将令牌写入 POST 数据。

def _helper(self, url, method="POST"):
    req = urllib2.Request(host + url)
    self.cookieMgr.add_cookie_header(req)
    try:
        if method == "GET":
            response = self.opener.open(req)
        else:
            for cookie in self.cookieMgr:
                if cookie.name == "csrftoken":
                    csrf = cookie.value
            values = { "csrfmiddlewaretoken" : csrf}
            params = urllib.urlencode(values)
            response = self.opener.open(req, params)
            code = response.getcode()
            info = response.info()
            content = response.read()
            return code, info, content
    except urllib2.HTTPError as ex:
        print str(ex)
        sys.exit(1)

def get_csrf(self):
    url = "/license/dummy"
    self._helper(url, method="GET")

def login(self, username, password):
    self.get_csrf()
    url = "/license/login?username=%s&password=%s" % (username, password)
    code, info, content = self._helper(url)
    if code == 200:
        #done!
于 2013-05-11T07:13:29.347 回答
0

开始阅读有关CSFR 和 ajax的内容。我通常使用提供的代码执行以下操作:

  1. 创建一个 csfr.js 文件
  2. 将代码粘贴到 csfr.js 文件中
  3. 引用模板中需要的代码|

如果您正在使用模板并且有类似 base.html 的扩展源,那么您只需从那里引用脚本,您就不必再担心其余的编程了。据我所知,这不应该代表任何安全问题。

于 2013-05-10T12:19:14.217 回答
0

csrftoken当您向 Django 发出请求时,您必须添加cookie 值。或者,您可以添加@csrf_exempt到 Django 后端以接受这些请求。

于 2013-05-10T10:36:38.433 回答