cordova-plugin-advanced-http
cordova-plugin-advanced-http copied to clipboard
[Bug] Cookies not being set/sent with redirected response/requests
I'm using an external API that is setting a cookie on a 302 redirect which this plugin does not seem to handle correctly.
I was able to always reproduce this issue in the following test case (I mocked these HTTP responses). I used a network capture tool like Charles to inspect the request/responses.
- Redirects are handled (
disableRedirect
is not enabled) -
GET http://www.mocky.io/v2/5bb2006d2e00009015927349
(redirects & sets cookie)
Location: https://www.mocky.io/v2/5185415ba171ea3a00704eed
Set-Cookie: redirected=true; Path=/; Secure; HTTPOnly
- (Redirected URL is automatically requested)
GET https://www.mocky.io/v2/5185415ba171ea3a00704eed
does not send any cookies as expected - (Manual request)
GET https://www.mocky.io/v2/5185415ba171ea3a00704eed
does not send any cookies as expected
Testing with an endpoint that sets cookies on a normal response (without redirect) works correctly. The subsequent request sends the stored cookie. (e.g. GET https://www.mocky.io/v2/5bb1fe132e00008535927339
)
I think this is a bug in the redirection handler/logic.
I was also able to confirm if I enable disableRedirect
, then the response cookie is correctly stored and sent in subsequent requests, however obviously I'd need to manually handle the redirects which isn't desirable.
Also I only tested on iOS. Not sure if this affects Android.
+1 on this. I have a situation similar to the OP. My login using POST
is based on cookies and the portal returns a 302 found
. This plugin does follow the redirect correctly, but ignores the cookies.
This problem is evident on both iOS and Android
In my project I've worked-around this by
- enabling
disableRedirect
- handle HTTP redirect status codes in http rejection
- extract URL from
Location
header - call the redirected URL recursively
Which is roughly
this.http.get(url, {}, {}).then(
data => {
...
}, (error: HTTPResponse) => {
// if response is a redirect
if (error.status > 300 && error.status < 400) {
this.handlRedirectResponse(error).then(
...
}
})
private handlRedirectResponse(http: HTTPResponse) {
// get redirect path
let redirectPath: string = http.headers['location'];
// fix up some redirect URL with spaces (it should have been urlencoded, but it's not)
redirectPath = redirectPath.replace(/\s/g, '%20');
// prepend the domain name
let redirectUrl = `${this.apiDomain}${redirectPath}`
return this.http.get(redirectUrl);
}
It's a bit dirty but works.
Hi longzheng, that's a good warkaround! I can confirm this is a problem, I'll need to fix.
Thanks @longzheng I've done something similar but glad to see @silkimen plans to address this in the core code!
+1 I can confirm this bug exists on both iOS and Android versions of the cordova plugin (using latest Ionic 3 framework). If it can help, this is the workaround I am using at the moment, following the idea of @longzheng :
this.http.disableRedirect(true);
return this.recursivePost(this.loginURL, body, headers);
and the extra function
recursivePost(url, body, headers) {
return new Promise((resolve, reject) => {
this.http.post(url, body, headers).then(
response => {
resolve(JSON.parse(response.data));
},
error => {
if (error.status > 300 && error.status < 400) {
let redirectPath: string = error.headers['location'];
redirectPath = redirectPath.replace(/\s/g, '%20');
let redirectUrl = this.SERVER_URL + redirectPath;
resolve(this.recursivePost(redirectUrl, {}, headers));
}
else {
reject(JSON.parse(error.data));
}
}
)
});
}
Just a note to say that this is still an issue, but I worked around it by catching the cookie from the header in the first response (before redirect) and calling the setCookie method directly hence it sends it with all subsequent requests
window.cordova.plugin.http.setCookie('/', cookieHeader, {})
Hi ! Thanks for your work.. Any new about this todo ?
Thanks to all for the solution! Not nice when the session cookie from the server is ignored that lightly...