I have two domain names (in two hosting locations). Domain 1
is a normal website with authentication. I am using Domain 2
as a place to just upload files (for storage). I am using angular-file-upload
https://github.com/danialfarid/angular-file-upload from client side.
My backend code is super simple and it is current working .. but without any form of authentication.
<?php
header('Access-Control-Allow-Origin: *');
$fname = $_POST["fname"];
if(isset($_FILES['file'])){
//The error validation could be done on the javascript client side.
$errors= array();
$file_name = $_FILES['file']['name'];
$file_size =$_FILES['file']['size'];
$file_tmp =$_FILES['file']['tmp_name'];
$file_type=$_FILES['file']['type'];
$file_ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
$extensions = array("jpeg","jpg","png", "gif");
if(in_array($file_ext,$extensions ) === false){
$errors[]="image extension not allowed, please choose a JPEG or PNG file.";
}
if($file_size > 2097152){
$errors[]='File size cannot exceed 2 MB';
}
if(empty($errors)==true){
move_uploaded_file($file_tmp,"images/".$file_name);
echo $fname . " uploaded file: " . "images/" . $file_name;
}else{
print_r($errors);
}
}
?>
Questions:
How to make sure the user is authenticated in Domain 1
before they can upload files? I mean I could just change Access-Control-Allow-Origin
but someone can easily go to Chrome Developer and do a POST upload from custom javascript.
Is there a way to do #1
without getting overly complicated? Is it possible to pass some cookie values?
I have full control of both hosting sites so I can do whatever I want.
Sharing a common secret
One way is to share a secret, wich is only known to Site A and Site B.
Suppose Site A and Site B know a common complex and non-predictable string salt
[randomness source].
If Site A authenticates a user, A creates a random string rndA
, a valueThrough
timestamp and then computes a hash like so:
sharedHash = hash( rndA + salt + valueThrough )
[ sharedHash, valueThrough , randA ]
If B computes the same sharedHash and the current timestamp is still smaller than valueThrough, client gets authenticated.
Letting Site A and Site B talk to each other
Alternatively, Site A and Site B might talk directly to each other:
While this technique requires reachability of Site A <-> Site B, the former technique even works, if Site A and Site B can't exchange HTTP-requests directly.
In both cases Generating cryptographically secure tokens might be of interest.
Other and stronger techniques certainly exist.
How's about sharing session in db like redis or mongodb?