You can use JSON Web Tokens for communicating securely across devices.
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA.
Source
You basically send a token with each request to sources you want to secure behind a login. Then server side you veryfy that token. Upon login you generate that token and include it in your response. In your frontend you can store the token in local storage on the client machine. For example jQuery has this plugin for local storage.
Here is a super basic example of what you need to do in PHP.
Do your login using javascript/jQuery. Send username/password to login.php for example and authenticate the user like you would normally do.
login.php
use \Firebase\JWT\JWT;
$salt = 'some_salt_string';
$algo = 'HS256'; // allowed ones
$params = array(
"iss" => 'http://example.com', // your own identification
"aud" => ['user_id'=>4324], // client identification
"iat" => time(), // start validity
"exp" => time()+(3600*24) // end validity
);
$token = JWT::encode($params, $salt, $algo);
// example data
$data = [
'example_1'=>'value 1',
'example_2'=>'value 2'
];
$response = array_merge($data,['token'=>$token]);
header('Content-Type: application/json');
echo json_encode($response);
auth.php
use \Firebase\JWT\JWT;
/**
* http://stackoverflow.com/questions/40582161/how-to-properly-use-bearer-tokens
* Get header Authorization
* */
function getAuthorizationHeader(){
$headers = null;
if (isset($_SERVER['Authorization'])) {
$headers = trim($_SERVER["Authorization"]);
}
else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
$headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
} elseif (function_exists('apache_request_headers')) {
$requestHeaders = apache_request_headers();
// Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
$requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
//print_r($requestHeaders);
if (isset($requestHeaders['Authorization'])) {
$headers = trim($requestHeaders['Authorization']);
}
}
return $headers;
}
/**
* http://stackoverflow.com/questions/40582161/how-to-properly-use-bearer-tokens
* get access token from header
* */
function getBearerToken() {
$headers = $this->getAuthorizationHeader();
// HEADER: Get the access token from the header
if (!empty($headers)) {
if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
return $matches[1];
}
}
return null;
}
$token = getBearerToken();
$salt = 'some_salt_string';
$algo = 'HS256';
$decoded_token = JWT::decode($token, $salt, $algo); // returns object
// you can access the audience properties to verify the user id against a requested resource
$user_id = $decoded_token->aud->user_id;
// finally check user id and either deny or allow access
javascript
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-storage-api/1.9.4/jquery.storageapi.min.js"></script>
<script>
var storage=$.localStorage;
function login() {
$.ajax({
url: 'https://example.com/api/login',
type: 'POST',
data: {
username:'Username',
password:'Password'
},
success: function (data) {
storage.set('auth_token',data.token); // store returned token to local storage using the jQuery plugin"value"
},
error: function () {
alert('Error occured');
},
});
}
function testApi() {
$.ajax({
url: 'https://example.com/api/test',
type: 'GET',
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'bearer '+storage.get('auth_token')); // append the token. Mind the space.
},
data: {
query:'value'
},
success: function () {
},
error: function () {
},
});
}
</script>
Include the auth snippet in your secure pages or better said API endpoints.