Search Unity

Unity Webrequest Cookie Header not being properly set

Discussion in 'Android' started by jelmertje, May 22, 2018.

  1. jelmertje

    jelmertje

    Joined:
    May 2, 2016
    Posts:
    9
    Hi, I'm having an issue with Unity.Webrequest, my code works fine in the editor, but it doesn't when I build to Android.

    My code logs in a user using a name and password and then gets a value from the server that it has to remember in order to identify itself the next times it serves or requests data. Getting this value works fine, but sending it back is failing on Android, while it works fine in the editor.

    Code (CSharp):
    1. string sessionCookie
    2.  
    3. public IEnumerator LoginUser () {
    4.         WWWForm loginForm = new WWWForm ();
    5.  
    6.         loginForm.AddField("data[User][email]", "name");
    7.         loginForm.AddField("data[User][password]", "pass");
    8.  
    9.         UnityWebRequest www = UnityWebRequest.Post ("http://192.168.1.2/api/login/", loginForm);
    10.  
    11.         www.SetRequestHeader ("X-Requested-With", "XMLHttpRequest");
    12.  
    13.         yield return www.SendWebRequest ();
    14.  
    15.         if (www.isNetworkError || www.isHttpError) {
    16.             Debug.Log (www.error);
    17.         } else {
    18.             string s = www.GetResponseHeader ("set-cookie");
    19.             sessionCookie = s.Substring (s.LastIndexOf ("sessionID")).Split (';') [0];
    20.         }
    21.     }
    22.  
    23.  
    24. public IEnumerator GetUserInfo () {
    25.         WWWForm form = new WWWForm ();
    26.         UnityWebRequest www = UnityWebRequest.Post ("http://192.168.1.2/api/getUserInfo/", form);
    27.  
    28.         www.SetRequestHeader ("X-Requested-With", "XMLHttpRequest");
    29.         www.SetRequestHeader ("Cookie", sessionCookie);
    30.  
    31.         yield return www.SendWebRequest ();
    32.  
    33.         if (www.isNetworkError || www.isHttpError) {
    34.             Debug.Log (www.error);
    35.         } else {
    36.             Debug.Log ("WebRequest succeeded");
    37.             Debug.Log (www.downloadHandler.text);
    38.         }
    39.     }

    I felt like my problem was very similar to this one right here, since I know through debug logging that my sessionCookie has the correct value.
    https://issuetracker.unity3d.com/is...es-not-recieve-all-the-set-cookie-header-data
    So I upgraded to Unity 2018.1.1f. Could this have been a version too far?

    Or am I missing something important that is vital to making this work on Android? Any advice is much appreciated!
     
    BitPax likes this.
  2. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    I don't see anything wrong with this code.
    So though debug logging you see that the cookie is correct on Android?
    Have tried to setup some proxy to monitor network traffic?
     
  3. jelmertje

    jelmertje

    Joined:
    May 2, 2016
    Posts:
    9
    I have checked to see what exactly the server receives and apparently, when doing the request two sessionID's are sent. (separated by a comma!).

    It appears that Android automatically appends the cookie header to the outgoing request resulting in a cookie header with two sessionID's.

    I tried this, to assert that the Header would only be set if it wasn't already.

    Code (CSharp):
    1. Debug.Log(www.GetRequestHeader("Cookie"));
    2.         if ( www.GetRequestHeader("Cookie") == null )
    3.             www.SetRequestHeader ("Cookie", sessionCookie);
    4.  
    5.         Debug.Log(www.GetRequestHeader("Cookie"));
    But this doesn't work. The debug shows that the header is null before I add my own cookie header, and it logs as it should be after I set it.
    I think this means that Android appends it's own header after Unity did what it is supposed to.

    For now I made it work by simply commenting out the line where I set the cookie, meaning that I now have code that depends on Android taking care of this automatically.
    I am still a bit worried though that this won't happen the same way on all current and future versions of Android, so if there is a way that assures my header is set properly and only once, I am still interested in a better solution.
     
  4. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    On Android there is a CookieManager in UnityWebRequest so it is expected for cookies to be sent automatically. There is no such thing in Editor for now. We are working on this to make it more consistent across platforms, but that's quite the future now.
     
  5. jelmertje

    jelmertje

    Joined:
    May 2, 2016
    Posts:
    9
    I see, and there is no way to turn this CookieManager off or edit it? Or is it generally dependable?

    I have it set up like this now:
    Code (CSharp):
    1.  
    2. #if !UNITY_ANDROID
    3. www.SetRequestHeader ("Cookie", APISessionCookie);
    4. #endif
    5.  
     
  6. prasetion

    prasetion

    Joined:
    Apr 3, 2014
    Posts:
    28
    hallo everyone, i am trying to ger API, and try to set the header, but the header does not setup correctly, i don't know why.

    Code (CSharp):
    1. UnityEngine.Networking.UnityWebRequest request = UnityEngine.Networking.UnityWebRequest.Get(url);
    2.                 request.SetRequestHeader("id", "abcdlksjdpa");
    3.                 request.downloadHandler = new UnityEngine.Networking.DownloadHandlerBuffer();
    4.                 yield return request.SendWebRequest();
     
  7. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    Not setup correctly as in not set at all? How did you check that?
     
  8. prasetion

    prasetion

    Joined:
    Apr 3, 2014
    Posts:
    28
    hi @Aurimas-Cernius , with our api, the header, if not setup correctly we will get error response in json. The error is not about isNetworkError or isHttpError. Actually I have checked using postman app, and it is working well. Then we try in unity, it still get error. I don't know why. I assume when i call setrequestheader need another way. if you have advice to solve myproblem, it would be great, thanks
     
  9. prasetion

    prasetion

    Joined:
    Apr 3, 2014
    Posts:
    28
    oh yaaa, i forgot something, when i call setrequestheader like mycode before and when i dont call setrequestheader in my code, both of them show the same error response in json.
     
  10. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    Use HTTP proxy like Fiddler to inspect the traffic. Sounds like your issue is elsewhere.
     
  11. Reza-HP

    Reza-HP

    Joined:
    Aug 27, 2017
    Posts:
    4
    I don't know if it late to continue this discussion or not but i ran to same problem 2 day ago just in android devices , I get unauthorized access , my code works fine in IOS and editor , I install an emulator and monitor the traffic with wireshark and figure out that just first time you want to call a web service an automated cookie is set by device so you have 2 cookies in your request . but as soon as you kill your app or quit it it wont set cookie automatically and everything works fine afterward , now the hard part is how to recognize if user close the app one or not ,to set a flag
    is there any way to know what headers is in a request ?
     
  12. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    Are you setting cookie yourself in request header? Because they are also managed automatically by the system.
     
  13. Reza-HP

    Reza-HP

    Joined:
    Aug 27, 2017
    Posts:
    4
    Thank for the replay
    First of all I am using unity2018.2
    and yes I am setting cookie by my self and i dont think in this version they are set automatically except the first call from android deceives
    my code work fine in IOS and Editor but fist call from android devices will send 2 cookies and get access denied from server but if i kill the app and run it again everything works fine
     
  14. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    2018.2 does have a cookie handler, so cookies do persist within same session for sure. We do set CookieManager object to handle cookies, if none is set.
    We only do set it if it's not set yet and only once, so if you set it yourself to something that does nothing, you should be fine.
    Our code for cookies is as simple as:
    Code (CSharp):
    1. if (CookieHandler.getDefault() == null)
    2.     CookieHandler.setDefault(new CookieManager());
    3.  
     
  15. Reza-HP

    Reza-HP

    Joined:
    Aug 27, 2017
    Posts:
    4
    CookieHandler seems not working in my code ????
     

    Attached Files:

  16. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    That is Java code. If you want to call it from your script, you have to use AndroidJavaClass and it's companions or write pure Java code and invoke that.
     
  17. J_P_

    J_P_

    Joined:
    Jan 9, 2010
    Posts:
    1,027
    So if we want to store cookie and use it for a future session, is there not a way to do this on Android?
     
  18. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    Sure you can. But you have to check first if you need to - in a single app instance cookies are managed automatically. To make them work across the session, you may need to implement it yourself. Note, that on some platforms they do work across the sessions too, but that's platform dependent. Not so on Android.