【问题标题】:Django authentication with curl and C++使用 curl 和 C++ 进行 Django 身份验证
【发布时间】:2013-01-21 12:40:15
【问题描述】:

我正在尝试创建一个 C++ 应用程序来登录 Django 服务器。我一直在寻找这个,但我还没有找到解决我的具体问题的方法。

我正在使用 libcurl 网站的示例之一来执行请求:

#include <stdio.h>
#include <curl/curl.h>

int main(void)
{
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1/");

        /* Perform the request, res will get the return code */ 
        res = curl_easy_perform(curl);
        /* Check for errors */ 
        if(res != CURLE_OK)
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));

        /* always cleanup */ 
        curl_easy_cleanup(curl);
    }
    return 0;
}

我找到了一个输入用户名和密码的选项:

curl_easy_setopt(curl, CURLOPT_USERPWD, "luis:123456");

但问题是我不知道 Django 是如何识别这个 curl 选项的。

其他可能性是完成 Django 提供的登录表单。我使用的表格是:

<html><body>
<form method="post" action="/login">
{% csrf_token %}
  {% if form.errors %}
    <p class="error">Login error</p>
  {% endif %}
<table>
<tr>
    <td>Username</td>
    <td>{{ form.username }}</td>
</tr>
<tr>
    <td>Password</td>
    <td>{{ form.password }}</td>
</tr>
</table>

<input type="submit" value="login" />
</form>

</body>
</html>

使用此选项,我的问题是我不知道如何使用 C++ 和 curl 获取和完成表单。

【问题讨论】:

  • 您是否可以访问 django 代码,或者它对您来说是一个黑匣子?因为您可以创建一个新的 django 视图,该视图接受用户名和密码作为获取参数(可能还有您的 c++ 应用程序的某种自定义身份验证令牌),然后将用户登录并使用 curl 访问该视图。
  • 是的,django 服务器是我的。我做了一个测试,发送我的用户并传入 url,视图已经实现了自定义身份验证。它有效,但不安全。

标签: c++ django authentication curl


【解决方案1】:

您需要将带有登录表单数据的 POST 请求发送到登录 URL - 除非 Django Web 应用程序提供不同的登录机制,但通常情况并非如此。

当您发送 POST 数据并且 Django 登录表单处理确实成功地验证了用户身份时,您将获得一个 cookie,您将在后续请求中存储和使用该 cookie。

另外请注意,登录表单使用csrf_token 标签,这意味着如果您没有在请求中发送csrftoken cookie 和带有表单数据的令牌,Django 将拒绝该请求。我建议您查看加载和提交登录页面时浏览器发出的 HTTP 请求。所有现代浏览器都有很好的调试工具来监控请求。

或者,如果您可以控制 Django Web 应用程序,您可以在登录页面的视图功能中禁用 CSRF 令牌验证。

【讨论】:

  • 我可以控制 Django 网络应用程序。如何禁用 CSRF 令牌?这安全吗?
  • 有一个装饰器django.views.decorators.csrf.csrf_exempt,您可以将其添加到您的登录视图中。对于登录,我想说删除它并不重要,因为 CSRF 漏洞利用通常需要您已经登录。有关详细信息,请参阅en.wikipedia.org/wiki/Cross-site_request_forgery。另请查看 Django 文档docs.djangoproject.com/en/dev/ref/contrib/csrf
  • 谢谢。使用 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "username=luis&password=123456");并禁用 CSRF,我可以登录 django 服务器。我可以隐藏 POST 选项吗?因为如果我用wireshark检查请求,我可以看到用户和密码,我认为它不安全。
  • 不,你不能。 HTTP 是纯文本协议,如果您想要安全通信,则需要使用 HTTPS。
【解决方案2】:

我不完全确定,但我认为 CURL 所做的是标准的 HTTP authentication。它不知道表单是登录表单。

【讨论】:

  • 没错 - 我想知道他是否可以从表单中制作 POST 以进行登录
  • 是的,但我不知道 Django 是否有可能识别出该身份验证
【解决方案3】:

查看正在发生的事情的最简单方法之一是安装wireshark,查看数据并使用它来设计您的curl选项。

【讨论】:

  • 基于行的文本数据:application/x-www-form-urlencoded:csrfmiddlewaretoken=SqoFeTva84MUjmgDAvkuRWb9zL83UDsf&username=luis&password=123456
【解决方案4】:

正如问题的原始海报所述:


解决方案

为了使用 curl c++ 实现 POST,我使用了 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "username=luis&amp;password=123456);,并且在 Django Web 服务视图中,我禁用了 CSRF:

from django.views.decorators.csrf import csrf_exempt
...
@csrf_exempt
def mylogin(request):

    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
           login(request, user)
        else:
            # Return a 'disabled account' error message
            return HttpResponse("Error\n")
    else:
        # Return an 'invalid login' error message.
        return HttpResponse("Invalid pass or user\n")
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-01
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    相关资源
    最近更新 更多