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