I am building an app in PHP Lumen which returns a token upon login. I am not sure how to proceed beyond this.
How am I supposed to maintain a session using these tokens?
Specifically, how do I store the tokens on the client side if I am using reactjs or vanilla HTML/CSS/jQuery and send them in every request I make for the secure part of my web app?
A session token is a mechanism that lets your embedded app authenticate the requests that it makes between the client side and your app's backend.
Session-based authentication has been the default method for a long time. With this method, a session, which is a small file that stores information about the user including unique session ID, time of login and expirations, and more, is created by the server and stored in the database after you log in.
The session token, also known as a sessionID, is an encrypted, unique string that identifies the specific session instance. If the session token is known to a protected resource such as an application, the application can access the session and all user information contained in it.
In the session based authentication, the server will create a session for the user after the user logs in. The session id is then stored on a cookie on the user's browser. While the user stays logged in, the cookie would be sent along with every subsequent request.
What I usually do is to keep the token in the local storage, this way I can persist the token even if the user leaves the site.
localStorage.setItem('app-token', theTokenFromServer);
Every time the user loads the page, the first thing I do is to look for the existence of the token.
token = localStorage.getItem('app-token');
If using react, I'd keep the token on the global state (using redux for example):
function loadAppToken(token) { return { type: 'LOAD_TOKEN', payload: { token }, }; }
With vanilla javascript I'd keep it on my connection utility. Which might look something like the following:
const token = localStorage.getItem('app-token'); export function request(config) { const { url, ...others } = config; return fetch(url, { ...others, credentials: 'include', headers: { 'Authorization': `Bearer ${token}` }, }); }
I'd still have a fetch utility in a react app, similar to the previous code, but I'd send the token in the options, by getting it in a redux middleware for every single request.
Let's assume you want to build an APP with.
You must forget about sessions when building REST API's.
REST API's are meant to be stateless, so they must not depend on sessions, they must process requests with only the data given by the client.
All the client wants to do is only to exchange some username
& password
for a token.
This is an example HTTP request
POST /api/v1/authentication HTTP/1.1 Host: localhost Content-Type: application/json { "username": "foo", "password": "bar" }
And the response is:
{ "token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }
How our API will process the authentication request?
It will check if a user with username foo
& password bar
is founded and it's active in DB
It will generate a JWT (Json Web Token)
It will return response containing the JWT
This is some super simple auth method, just for example.
public function authAction() { /** Get your payload somehow */ $request = $_POST; //Validate if username & password are given/ $user = $this->model->auth($username, $password); if(!$user) { //throw error for not valid credentials } $jwt = $this->jwt->create($user); //return response with $jwt }
As you see they are no sessions set or anything.
How our client side will process the response?
The client could use some package like superagent for handling the requests & responses to our API this way the process will be simplified to this:
let data = { username: email, password: password }; request .post('/api/v1/authentication') .set('Content-Type', 'application/json') .send(data) .end(function (error, response) { //response.body.token });
You could use some 3RD PT package for generating and validating JWT instead of writing it yourself.
Look at this package, you can see how it's done.
And remember to always create strong signatures. I recommend using RSA keys
I am not advertising or supporting this project, just found it useful to share it here. I had never used it, I'm using something similar to this on my NodeJS projects.
They are two ways as you already know localStorage
& cookies
For me I am using cookies, because:
But it's all up to you.
From now on every request to server you must include your JWT.
In your REST API you must write a method to validate the JWT and exchanging it for user object.
Example request:
let jwt = ...; //GET IT FROM LOCALSTORAGE OR COOKIE request .get('/api/v1/posts') .set('Content-Type', 'application/json') .set('Authorization', jwt) .end(function (error, response) { });
How API will process this request
public function postsAction() { $jwt = $this->headers->get('Authorization'); if(!$this->jwt->validate($jwt)) { //throw unauthorized error } $user = $this->model->exchangeJWT($jwt); //Your logic here }
If you are using cookie to save your JWT, be careful with setting the expire dates.
The cookie expire date must be equal to the JWT expire date.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With