How to save user credentials in Rest API? - php

I'm going to make a Rest API, this working in the following way:
user send an header with a token string
api check if the token is valid and if are available in a xml file
if yes, in this xml file I return the connection of database (there is also information about the user)
now I want store somewhere the information of the user that's performing the transaction
I thought to the header but how I can store some information on the header? There is also another way?

If the validity of token is too long.
You can use redis to save the user info corresponding to the token.
Something like this.
Further you can simply query using token to get user object.
{token : {user Object}}
You can write delete token script for deleting expired tokens.

Related

How to expire JWT if a new one is generated

I am totally new in JWT implementation and an issue came up.
I have built a user login authentication with JWT in php. On user login, if user's credentials are valid then response of login API is a token which is stored as a cookie and instead of having $_SESSION variables, I get user's data by making an API call to decode token and retrieve user's data on every page of web application.
If user wants to update his personal details (name, e-mail etc) I want to generate a new JWT based on new details and to force previous one to expire or somehow make it invalid. So, in future API calls previous token must be invalid.
I thought of storing tokens on database but this is not right I suppose.
How can I make it works?
Stateless authentication (in this case JWT) stores the user session data on the client side (browser).
The data is signed by the key of IdP to ensure the integrity and authority of the session data.
Since the user session is stored on the client side, the server only have the capability to verify its validity by checking whether the payload and the signature match.
One of the disadvantages is that you cannot revoke the session anytime: since the user session is stored at client side, the server does not have any rights to delete the session.
• What you can do:
You can remove the stored JWT on the client and put this in a db blacklist and check everytime someone calls the APIs
You cannot without making the api stateful.
So either you store a reference to the JWT in your database and delete it or you could blacklist the revoked tokens and check on authorization if the token was blacklisted and therefore is revoked.
You can do two things:
First delete the old JWT token and insert new one.
Or create an field (is_expired) in database to check the status of token and default should be false so when you create new one, it marked to true and the old one must change with false value.

Share common authentication token between web and app

I would like to create a website and app where users can search a song and collect it into a public list (saved to a database). Therefore, I would not like to let the user authenticate himself just to add 1 song to the list. Because you need to provide a token in order to search, I've found several options:
I will save the token into the database (refresh every hour using a CRON job), and when the user wants to search, I will retrieve the code and append it client side so the request will be successful. This, of course, exposes the token, even though it can only search, it is not really safe. PHP is no option, as it has to be a website and an app
I need to let everyone log in which is very annoying
I need to make a PHP script that will receive some endpoints from the client side and will execute it server side and send the response back. This, however, does not scale really well when there are a lot of users and the rate-limiting from one IP will soon be activated.
Are there any other options I can try?
EDIT:
The songs should be searched by calling the Spotify API, not everyone has Spotify, therefore I was thinking about one token that could be shared
Less annoying but not secure:
Mobile App
First time the app is used:
Require authentication and capture the device UUID.
Store the device UUID in the database which is related to the authenticated user and also related to the user's play list.
Next time the app is used the device UUID already exists in the database so assume the related play list is the one to use.
Browser
First time the page (or after clearing cookies) is used:
Require authentication and set a long-lived cookie.
Store the cookie in the database which is related to the authenticated user and also related to the user's play list.
Next time the page is used the cookie will already exist so assume the related play list is the one to use.
If you're looking to use OAuth as a means of TLS between the server and client then each user must authenticate against the server with a request of information.
Since, I assume, this is not a public API (for anyone to access data), you only want your client app to be able to authorise such requests.
In this case, you would not need to send a 'scope' to the authentication server, simply just generate a resource token but FORCE the user to login.
Using that resource token, the client will send a second request to the resource server. Inside this request should hold the ACTION and DATA for that request and on receipt should then delete that token from the database. There is no need for a CRON job.
Client -> Authentication Server
<- Resource Token (OK)
<- Status BAD
Client -> Resource Server { Resource Token, Action, Data }
<- Status OK
<- Status BAD
Check the token exists and "in-date"
Check that the action is permitted
Check that the data is more than 1 song
Execute the insert, remove the token and return a response header
The reason you do not need a CRON job is because you should set a timeout for the token. For example, add a (TIMESTAMP) created DEFAULT CURRENT_TIMESTAMP to the database, pull the row out of the database for that token and ensure that it wasn't created n minutes ago, if it was then its void (expired) and can no longer be used.
Here is a URI example for the resource server:
/api/resource_token/action?data=
Of course, data should be a POST parameter but, for this, it was easier to show it as a GET request. It doesn't need to hold ALL the data, it could be anything like:
?song=[{"artist": "foo", "song": "bar"}]&type="json"
Using AltoRouter it would look something like this:
$router->map('GET|POST', '/api/[*:token]/[*:action]', function($resourceToken, $requestAction) {
foreach(array('Song', 'Type', 'PlaylistId') as $param)
if(!isset($_POST[$param]))
die(...Return your response header error...);
if(($token = SomeModel::getToken($resourceToken))->isValid())
SomeController->using($token)->execute($requestAction);
die(...Return your response header success...);
}, 'API');

JWT token login and logout

Hi I am creating mobile native application that uses REST API endpoints to communicate with server side.
I have had previous experience developing native clients, but I have simple token (random generated string) stored in DB in the same table where user information is stored. So it is like sessions used in browser, but instead of cookies each request has token in the header.
Recently I discoreved JWT token. It seems to be great way to secure endpoints which are private. You can request token from mobile client providing you pass + login and get generated token in response.
But the one important thing is that this token is not stored anywhere on the server, server verifies the token using secret word, which is private for the server like private key.
That's okay for secured endpoints, but what to do if I require user session, for example how do apps like Facebook, Amazon, Aliexpress ... work, they have ability to use the app without providing credentials, just navigating through the store, but require logining in when user want't to make purchase. And after that user session is kept for some time.
This can be implemented with the JWT token without any problems, but when user need to logout, what to do in this case ? Token is not stored anywhere on the server, so how can I destroy this token, to make it invalid ?
If token is stored in the database, API is not stateless, as REST API should be.
So in general there is no way to keep user logged in in stateless API, am I right ?
I have some ideas how to implement this using JWT token, but again this will not be stateless API, as I understand.
Create the list of expired tokens
Store JWT token in the database, but what is the purpose of self descriptive token (JWT) in this case if it is stored in the database, the main idea of JWT token to keep all information with token, as I know.
Please suggest what is the best way will be in this case, and correct me if I have mistaken.
Thanks.
If you're using JWTs, then you can't have a server side state in order to properly logout the user without defeating the purpose of using JWTs in the first place. The best option though if you want to do this is to have a last logout date stored in the DB and in the JWT, and if these don't match you logout the user (without updating the date in this case). However, you now have server side state.
Storing logged out tokens in the DB seems like overkill though.
An alternative option is that you could generate a 128 bit token generated by a CSPRNG, store this using SHA-256 in the database, and then use the unhashed value in a web token. This way you can simply delete the entry in order to logout the user server side. This is the more secure option as you now have a way to properly expire tokens and sessions on the server. If a user changes their password, or wants to secure their account by logging out other sessions you now have a way to do this.
JWT authentication is basically happens on both the client side and server side.
When the user sends Username and password to authenticate. its checked against the db and if valid a joken is generated and sent back to the user. There are multipe API's for generating the JWT token, you can check out http://jwt.io/
Once the token is generated and sent back, it needs to be sent along with header in each request and needs to be validated, on the server side, before serving the API back to the user.
There is no need to store the the token as the API itself will allow you to decode it on the server side.
How i am doing it:
I generate a random id (I call it validation code) and store it in database when user signup, encode it in jwt.
Whenever any request is made with jwt, I check the validation code, if it is correct: access is granted.
To expire the session like after changing password, I change the validation code in DB.
If you need to logout a user, provide a logout link. The server should reset the session data by encoding the token with any empty array for example. The user will have a valid session but will not have the valid information to validated them.
Valid Token at login
$data = array("id"=>1,"user_type"=>"Admin");
$token = JWT:encode($data, $key);
Validating Token
$token = $_POST['token'];
$data = JWT:decode($data, $key, $hash);
if($data.id){
return "valid token";
}else{
return "invalid token"
}

Security issue with Facebook JS SDK

I am using the facebook JS sdk to login a user. These are the steps that I follow:-
1) I use the FB.login(...) to get the details of the user.
2) Now, after receiving the details from Facebook, I send a POST request using jQuery's $.post(..) function to a php page say FBUser.php with the parameters - name,uid(Facebook User Id),email and access_token for publish_actions.
3) Now in the FBUser.php page, I do all the stuff like converting the short-lived-token to long-lived and then I check that if the uid received is present in my users table. If it is not, I create a new user, else I log in the old user. Today, I just realized that I was making such a big security compromise because anyone can send a POST request to the FBUser.php page with a uid of an existing user and get access to his account. But, on the other hand I am sure that some big websites also use the JS SDK. So obviously, I am wrong somewhere. What would be the correct procedure to log in the user securely and preventing his account getting hacked?
You should match the app and user id first, then you should check the access token, like this:
graph.facebook.com/debug_token?input_token={token-to-check}&access_token={app-token}
You can get the app token from https://developers.facebook.com/tools/accesstoken/
You can get the uid of the user using the access token that was sent to you, by using this token to access Facebook graph and query "/me".
You shouldn't relay on the uid that is sent by the client. My application only receives the access token and gets the rest of the data from a server-to-server call.

SoundCloud oAuth Token - confused about how to sign in after initial 'connect'

from the docs:
You should now store the access token in a database. Associate it with
the user it belongs to and use it from now on instead of sending the
user through the authorization flow.
On the front-end, we are using the javascript connect function, but then we want the PHP side to write some user info to the db.
I understand how to actually receive the authorization/token and it is implemented. Then I store the token in the user database next to the user's ID (that we generate). That's all fine.
But when the user re-visits our application and is logged into Soundcloud, What do I do with this token? As stated above, I should automatically log them in? What exactly is the process here? I am confused about what I have to check against.

Categories