I am using the Slim Framework to create a stateless REST API. Before using this I created a SESSION on server side with session check on every page. But now, I don't know how to control it.
I have an api_key in my database for each user. After a user signin, I respond with a api_key and redirect the user to index.php. But the api_key is not retained. How can I pass the api_key to each page with Javascript? Reason being if someone wants data from my REST API, they have to send me an api_key and also if the user logged in before I don't want to show login page again.
Here is my REST API part:
$app->post('/userlogin', function() use ($app) {
verifyRequiredParams(array('email', 'password'));
$email = $app->request->post('email');
$password = $app->request->post('password');
$objUserRegLog = new UserRegistrationLogin;
$result = $objUserRegLog->getUserByEmailAndPassword($email, $password);
if (!$result) {
$response["error"] = true;
$response["message"] = "Error! Invalid e-mail address or password.";
} else {
$response["error"] = false;
$response["id"] = $result["id"];
$response["email"] = $result["email"];
$response["api_key"] = $result["api_key"];
}
echoResponse(200, $response);
});
$app->get('/students', 'authenticateStudent', function() use ($app) {
$objStd = new Students;
$result = $objCases->getAllStudents();
if (!$result) {
$response["error"] = true;
$response["error_msg"] = "An error occured.";
$status_code = 404;
} else {
$response["error"] = false;
$response["cases"] = $result;
$status_code = 200;
}
echoResponse($status_code, $response);
});
function authenticateStudent(\Slim\Route $route) {
$headers = apache_request_headers();
$response = array();
$app = \Slim\Slim::getInstance();
if (isset($headers['Authorization'])) {
$db = new DbOperation();
$api_key = $headers['Authorization'];
if (!$db->isValidStudent($api_key)) {
$response["error"] = true;
$response["message"] = "Access Denied. Invalid Api key";
echoResponse(401, $response);
$app->stop();
}
} else {
$response["error"] = true;
$response["message"] = "Api key is misssing";
echoResponse(400, $response);
$app->stop();
}
}
And the call with AJAX :
$.signin = function() {
var inputVals = $("#form_signin").serialize();
$.ajax({
url : "api/v1/userlogin",
data : inputVals,
dataType : "json",
type : "post",
success : function(response) {
if (response.error) {
$(".popup").trigger("click");
$(".modal-title").html(response.message_title);
$(".modal-body").html(response.message);
} else {
window.location.href = "index.php";
}
console.log(response);
}
});
return false;
}
Well, you need to understand that every request the client sends to your server is independent, so you need to put a variable (the token) in the client system in order to let him to send it in every request, so you know who is talking to your server all the time. Start reading this: http://www.w3schools.com/php/php_cookies.asp
Once you understand what are and how cookies work, try to read further about authentication and authorization topics.
You have three ways to provide such information.
Cookies
In most cases, if you have a login screen, you want to use cookies as mentioned by Hector. One potential problem with cookies, some people do not want them from "random" websites. However, the good thing is you can close your tab, reopen it, and you can still be logged in (it depends on the type of cookie, but in most cases you want to use this type).
Query String
One other way, tedious, is to add a query string parameter with the session identifier. This also means you must make sure that each single link on your page includes that session identifier. Also, it is generally viewed as a security issue because people who look over your shoulder can see the session identifier (frankly, unless they have a photographic memory...) For people who block cookies, this is another way. However, since it is using the exact same type of session identifier, you may be infringing on what the user meant when blocking cookies.
HTML Code
The last way, which requires even more work, is to put the value in the HTML. For example, you could use a <meta ...>
tag. At least that way it is hidden from people looking over your shoulder. But you still need to transmit it when someone clicks on your links, somehow. That means you must load any other page using a POST in JavaScript. That's rather unconventional. And just like with the previous method. You may be infringing on the user's will of "no tracking please".
What about Security?
The most secure is to have an HTTPS connection with a cookie marked as HTTP-only (i.e. JavaScript cannot access it, so it cannot temper with it.)
All other methods have additional security issues.