【问题标题】:Unity Web Request + Django: CSRF token missing or incorrectUnity Web Request + Django:CSRF 令牌丢失或不正确
【发布时间】:2018-10-23 02:57:27
【问题描述】:

我从 Django 收到一条错误消息,指出“CSRF 令牌丢失或不正确”及其标准错误消息。当您使用标准浏览器和 Django 服务器时,许多其他问题已经涵盖了正确的响应,但我试图让 UnityWebRequest 与 Django 很好地配合。

从概念上讲,我有两个步骤。首先,我在登录页面上调用 GET 请求,解析表单中的 csrfmiddlewaretokenset-cookie 标头中的 csrftoken

然后,我创建了第二个 UnityWebRequest,其中包含“referer”作为标头,csrftoken 作为 cookie 中的标头。我会在表单中添加用户名和密码以及csrfmiddlewaretoken,但无论哪种方式都会出现错误。

是否需要设置其他标头或 cookie?我认为我的问题是我试图在 Unity 中模拟 Web 浏览器的行为,这很复杂。

    UnityWebRequest loginPage = UnityWebRequest.Get("https://dividedsky.herokuapp.com/accounts/login/");
    yield return loginPage.SendWebRequest ();
    if(loginPage.isNetworkError || loginPage.isHttpError) {
        Debug.Log(loginPage.error);
        yield break;
    }

    // get the csrf cookie
    string SetCookie = loginPage.GetResponseHeader ("set-cookie");
    Debug.Log (SetCookie);
    Regex rxCookie = new Regex("csrftoken=(?<csrf_token>.{64});");
    MatchCollection cookieMatches = rxCookie.Matches (SetCookie);
    string csrfCookie = cookieMatches[0].Groups ["csrf_token"].Value;

    // get the middleware value
    string loginPageHtml = loginPage.downloadHandler.text;
    Regex rxMiddleware = new Regex("name='csrfmiddlewaretoken' value='(?<csrf_token>.{64})'");
    MatchCollection middlewareMatches = rxMiddleware.Matches(loginPageHtml);
    string csrfMiddlewareToken = middlewareMatches[0].Groups ["csrf_token"].Value;

    /*
     * Make a login request.
     */

    List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
    //formData.Add( new MultipartFormDataSection("username=fake") );
    //formData.Add (new MultipartFormDataSection ("password=notpass"));
    //formData.Add(new MultipartFormDataSection("csrfmiddlewaretoken=" + csrfMiddlewareToken));

    UnityWebRequest doLogin = UnityWebRequest.Post("https://dividedsky.herokuapp.com/accounts/login/", formData);

    doLogin.SetRequestHeader ("referer", "https://dividedsky.herokuapp.com/accounts/login/");
    Debug.Log (doLogin.GetRequestHeader ("cookie"));
    doLogin.SetRequestHeader ("cookie", "csrftoken=" + csrfCookie);
    Debug.Log (doLogin.GetRequestHeader ("cookie"));

    yield return doLogin.SendWebRequest ();

    Debug.Log (doLogin.downloadHandler.text);

【问题讨论】:

    标签: django unity3d csrf django-csrf


    【解决方案1】:

    (2020 年编辑:另见乔纳森的回应)

    事实证明,最后一个重要部分是设置 X-CSRFToken 标头。

    doLogin.SetRequestHeader ("referer", "https://dividedsky.herokuapp.com/accounts/login/");
    doLogin.SetRequestHeader ("cookie", "csrftoken=" + csrfCookie);
    doLogin.SetRequestHeader ("X-CSRFToken", csrfCookie);
    

    【讨论】:

      【解决方案2】:

      只是对这篇文章的更新,因为我自己试图用它来通过 Unity 发布到 Django。该代码很好,只需进行一次更改。以下代码行将导致错误,不应与 Unity 2018.3 或更高版本一起使用。

      doLogin.SetRequestHeader ("cookie", "csrftoken=" + csrfCookie);

      这是因为 Unity 自己管理 cookie,因此您不应该设置 cookie 标头。一旦我删除了那行代码,其余的代码就对我有用了。

      【讨论】:

        猜你喜欢
        • 2012-01-09
        • 2013-01-12
        • 2014-07-12
        • 2017-09-09
        • 2011-12-26
        • 2014-03-29
        • 1970-01-01
        • 2021-07-14
        • 2021-11-13
        相关资源
        最近更新 更多