UnityWebRequest WebGL Missing Cookie Response Header

Viewed 249

I'm posting log in form data containing username and password to an endpoint using Unity. I receive a success response containing expected credentials (as a session cookie) and subsequent communications are completed successfully when testing this in the Unity Editor.

When I deploy and build the project as WebGL I do not receive the 'Set-Cookie' header from my log in request. This causes all subsequent communications to fail unauthorized 401.

  • The log in WebGL post returns a success response.
  • When inspected in the browser, I see the success response returns the expected session cookie credentials with the header 'Set-Cookie'.
  • But the UnityWebRequest returns null when queried for 'Set-Cookie' response header. Some headers are still present, but most appear stripped.
  • WebGL build is deployed and played from https enabled server - this is a different server from the log in server

I think there is some security (CORS?) stripping these credentials before the response is returned to my program. Allow credentials and Origin response headers appear correct. 'Set-Cookie' response header format is:

Set-Cookie: SESSION=tvohm-example-session; Path=/tvohm-example-path/; Secure; HttpOnly; SameSite=Lax

Minified:

IEnumerator LogInCoroutine()
{
    using var request = new UnityWebRequest("https://tvohm-example-url.com/login")
    {
        method = UnityWebRequest.kHttpVerbPOST,
        uploadHandler = new UploadHandlerRaw(UnityWebRequest.SerializeSimpleForm(new Dictionary<string, string>()
            {
                { "username", "tvohm" },
                { "password", "ilovestackoverflow" }
            }))
    };
    request.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
    yield return request.SendWebRequest();
    if (request.result == UnityWebRequest.Result.Success)
    {
        Debug.Log(request.GetResponseHeader("Set-Cookie"));
        // Editor returns expected session cookie
        // WebGl returns null
    }
}

Invoked:

StartCoroutine(LogInCoroutine());
1 Answers

you cannot read nor write the "Set-Cookie" header in javascript, because the browser hides it from you as it is a forbidden header. https://fetch.spec.whatwg.org/#forbidden-header-name The browser will handle the cookies for you (thus crop that header out of your response headers so that you cannot access it anyhow) and add the Cookie header in your requests automatically, so that you cannot give away the crucial credentials that is stored in the "Cookie" header for example.

If you want to get the Cookie attached to your Request header by the browser, you have to tell the browser to do so, by adding

{credentials : „include“} 

to the javascript fetch function. Because Unity translates nowadays the c# UnityWebRequest to the javascript fetch(url, options) function. In the past UnityWebRequest was translated to XMLHttpRequest. What you want to do is to override the fetch() function in your Javascript or HTML file after Unity is built for webGL

<Skript>
 fetch = function( url,data) {
        console.log("url received: " + url);
        if (url.indexOf('https://www.replacethatwithyourserveraddress.com/') === 0 || url.indexOf('http://localhost:4000') === 0 || url.indexOf('http://127.0.0.1:4000') === 0) {
          data = {...data, ...{credentials : "include"}};
          console.log("withCredentials set to true " + JSON.stringify(data) + " url: " + url );
        }  else {
          console.log("withCredentials NOT SET for URL: " + url);
        }
        return originalfetch(url,data);
      };
</Skript>

Read more about this here:

https://braveyourself.de/cors-xmlhttprequest-unity-webgl-rest-netzworking-build/

Related