Authentication model for Android application - php

I going to build a system which have 2 part:
1. PHP Website (CakePHP).
2. Mobile application (Android & iPhone).
User must login with usr&pwd to use my system(web and mobile application). But i don't have a lot experiences with user authentication. What should i store: usr&pwd, token string. I want to find an "user authentication model" for my system (Web and Mobile application).
Is there anybody have experience about user authentication. Anybody know how to implement this?

This is what we do for our applications,
First we send a username and a password to the server from our application.
At the server, they authenticate the credentials and return a response which is combination of a request token and sucess flag.
In our applicatoin, we check the sucess flag. If its set to true, we save the request token and use it for all the next outgoing requests to the server.
Now when the server receives a request, it checks the database to see if a user has this token.
If it does, it checks the time in which the last request was made.(This is to handle cases when user login is timed out.). If the difference between the current time and the last request time is more than the limit you set, you responsd to the application that a fresh login request is required to generate a new token. Otherwise you continue with the request and respond with the results.
This is how the server side guys in my workplace does it. Im work on the client side. But this is basically what is done.
Edit: About the token.
Its basically a 32 character string which is generated with a random generator method. So when a user sends a login request and the login is success, we create a token using the generator method and store that into our server database as the users request token along with the current time and date.
So when the user sends another request to ther server, we first take the token and check if a user exists with that token. If there is, then the next check is to see if this is some old request token. So we check the current time with the time saved in the database. If the request was sent before the limit (Eg 5 mins) then we update the last request time in the database with the current time and return the result to the client.
With this method you are kind of doing an authentication for each request by checking the token and the last request time.
Suppose you want your app to be logged in all the time until the user explicity logs off. In that case you do not need to check for each request time. All you need to do is save the request token on the client device. And when the user signs out, delete the token from the client. So he will be required to login the next time as he has no token. Its a bit more secure to save a request token on the client device than saving a username and password in this scenario.
There are many functions out there for generating random tokens.

Related

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');

Firebase: how to check client side session with php server side script

I'm authenticating client side throught Firebase SDK the users to my app.
A clientside session is then started. I want the user then to be able to post to PHP endpoints some data. I want the PHP script to check if the request is coming from a authenticated user and then validate the rest of the data. If everything is ok, we finalize the operation.
I thought to do it like this:
User is authenticated client side
On Auth event a request for a JWT token with the user id in it is issued client side via ajax to a dedicated PHP script. Once the token is generated it is stored in a session cookie.
The form submit will carry the JWT token and the endpoint will decode the token and check if the uid stored in it is a valid user id registered in the Firebase DB.
Good or terrible idea from a security point of view?
First rule of thumb is that in order to validate a Firebase-generated JWT, you need the secret to your Firebase. Second rule of thumb is that your Firebase secret should never be sent or stored on a client.
Given that, to validate a JWT via PHP, you will need to use a library which decodes it and verifies it has been signed by your Firebase secret. Once you've verified that, I would look at the JWT's uid and see if it matches the uid of the user who owns the resource.

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"
}

Simple token-like authentication

Does the following authentication system seem reasonable:
Client calls the login end point with a user name and password to the main server. The main server sends this off to another authentication server (which will receive no further mention), which returns a yes/no if this is valid and a user ID that the main server is aware of. If yes, generate a random token (using some crypto library that spits out random strings), and store the hash of this (using PHP's password_hash()) and an expiry 12 hours from now on the user record. Return the token to the client.
Client now adds "Authorization: Token TOKEN+HERE+ABCD1234" to their requests to other endpoints. The server ensures that the hash of the token in the auth header matches the one in the database (using salts through PHP's password_verify()), and that the expiry hasn't been hit. If it doesn't match, or the expiry is exceeded, then send back a 401.
Seems at least as secure as basic HTTP authentication, which just has the base-64 encoded user:password in the header? The reason I'm considering this scheme over basic is that the main server won't store the username/password that the authentication server is using to log in.
What am I forgetting? Is this grossly insecure?
Your scheme is not that different from the standard server-side sessions where SESSION-ID is normally nothing more than a random token and stored on the client side within a cookie, with 2 improvements:
Instead of a cookie you would use Authorization header to deliver the token. This acts as a CSRF protection.
You would hash a token on the server-side. This helps against session hijacking in case someone gets access to your token-store on the server-side.
If you see the oAuth process of Google then you will get idea of how Authorization works for them.
They have different servers for Authorization and API calls. User sends authentication details to Authorization server and receive a code. Google is having process of taking user consent to access details but you can skip this process to take consent and just return code on successful details.
This code can be further used to get the Access Token from the API server. So your first request to API server would be to get the Access Token. Google is having facility to refresh your Access Token as well.
And all subsequent request to API server must contain Access Token. So you seems to be missing this Code exchange process to make it more secure.
More info: https://developers.google.com/identity/protocols/OAuth2

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