Saturday, 27 October 2018

withCredentials does not work when uploading files

My backend checks if a user is authorized to upload a resource with the following code:

<?php
if(!isset($_SESSION["id"])){
    http_response_code(401);
    die("Error. Unauthorized user.");  
} 

For this to work, developing angular app running on angular.example.com:4200 needs to send session cookies cross domain to example.com. I normally do that with just enabling {withCredentials:true} when sending a request. For some reason, this does not work when uploading a file with the code below:

//no cookies sent in this example   

import { HttpClient, HttpEventType } from '@angular/common/http';


//function
const fd = new FormData();
for (let i = 0; i < files.length; i++) {
  let file = files[i] as File;
  fd.append("myfile[]", files[i], files[i].name);
}
this.httpClient.post("https://example.com/upload.php", fd, { reportProgress: true, observe: "events", withCredentials: true }).subscribe((event) => {
   console.log(event);
// show upload progress code here
});

server response:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://angular.example.com:4200
Cache-Control: no-store, no-cache, must-revalidate
Connection: close
Content-Length: 25
Content-Type: text/html; charset=UTF-8
Date: Thu, 25 Oct 2018 13:29:04 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Server: Apache/2.4.33 (Unix) OpenSSL/1.0.2n PHP/7.2.4 mod_perl/2.0.8-dev Perl/v5.16.3
Set-Cookie: PHPSESSID=9e03dc7c6c6a3ccd4d1d87a1af135b86; path=/
Vary: Origin
X-Powered-By: PHP/7.2.4

request:

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US
Access-Control-Request-Method: POST
Connection: keep-alive
Host: example.com
Origin: https://angular.example.com:4200
User-Agent: useragenthere


No cookies are sent in this case, but if I use this code instead, than they are sent normally:

//cookies are successfully sent
for (let i = 0; i < files.length; i++) {
  let file = files[i] as File;
  fd.append("myfile[]", files[i], files[i].name);
}
this.httpClient.post("https://example.com/upload.php", fd, { withCredentials: true }).subscribe((event) => {});

It looks like that extra options mess up with withCredentials. What should I do to fix this issue?


This is my apache directive in example.com virtual hosts that handles CORS for all subdomains and ports:

SetEnvIf Origin ^(https?://.+\.example\.com(?::\d{1,5})?)$   CORS_ALLOW_ORIGIN=$1
Header append Access-Control-Allow-Origin  %{CORS_ALLOW_ORIGIN}e   env=CORS_ALLOW_ORIGIN
Header append Access-Control-Allow-Credentials true
Header merge  Vary "Origin"



from withCredentials does not work when uploading files

No comments:

Post a Comment