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

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.

Related

How to submit scores securely from app that uses only facebook login?

Our android app only has facebook login.
Here's what happens in server:
A user is created when a POST request is sent using facebook's user access token in body.
Whenever a user gets created via POST request, an api token is generated and sent as a response as follows:
{"message":"User Successfully Created","api_token":"ACITyBKf0jKrfqOFumTMcaEEJ8jU151crRdESMPmBj8zbeENslULHfNXlKeo"}
I did this because the api token that is generated in the server is stored in android app's local storage and is needed to make other requests.
Now, if the user already exists in the server, the response would be
{"message":"User Already Exists!!","api_token":"ACITyBKf0jKrfqOFumTMcaEEJ8jU151crRdESMPmBj8zbeENslULHfNXlKeo"}
This is in case the user deletes the app and installs again.
Now, to submit score, a PATCH request is to be sent with:
Headers:
Content-Type:application/x-www-form-urlencoded
api_token:ACITyBKf0jKrfqOFumTMcaEEJ8jU151crRdESMPmBj8zbeENslULHfNXlKeo
fb_id:xxxxxxxxxx
Body:
distance:2
golds:19
xp:23
(Note: I tested the above request using postman)
Now, the problem is that I spotted a loophole.
A person can find out their facebook user access token and their facebook id anytime. So, if they make a POST request with that user access token, they will receive the api_token (In the "User Already Exists!!" response). And once they have api_token and fb_id, they can make a PATCH request to modify their scores to whatever they want.
What am I doing wrong? How can I secure my server from being hacked like this?
Please help me. I am a beginner in api design.
Thanks
If their API token is available to them in the app at all, that's probably a bad thing. If its not available to them in the app, say they're just forging in-app POST requests and retrieving the raw data, then they're probably trying to hack or pentest the system.
If that's the case, maybe sending the unencrypted API key via POST in the first place is a bad idea. If their API key is all they need to start doing bad things to your system, why ever give it to them in the first place?
Because your app needs it to remember them. What about something like this:
New user, server md5 hashes their API key and sends it to them to be stored.
Existing user, server md5 hashes their api key and sends it to them to be stored (if needed)
Official Existing Score change occurs: app re-md5 hashes the already hashed api key, sends that with the PATCH request. Server has database with doubly hashed api keys which it finds yours and identifies you as the user, and things go on normally from there.

Ionic Token authentication php Server - Security questions [duplicate]

I have two applications:
server ( REST API Server)
node js
Express
jsonwebtokens
express-jwt
mongoose
client (Portable Front-end)
bootstrap
Angular JS
local-storage
angular-facebook
angular-jwt
Lateron, the client app will be ported for android, iphone and other platforms using phonegap. For OAuth, I am using Facebook as the provider. Now, I just realized JSON Web Tokens are the way to go for this kind of set up. My question is an architectural one rather than syntactical one - how to manage a secret key when signing the facebook access token and user id with JWT in nodejs?
So this is how the flow works in my app:
Angular client has a Login button
User Clicks the button > Facebook Auth starts
Client receives user_id and FB Access Token
Client sends[POST json body] both user_id and Access Token to Node+Express Server at 'http://server.com/auth/login'
Node Server has applied express-jwt to all routes except /auth/login with a
var expressJwt = require('express-jwt');
var jwt = require('jsonwebtoken');
app.use(expressjwt({ secret: ''}).unless({path: ['/auth/login']}));
Node server receives data from req.body, fetches all profile details from facebook using the JavascriptSDK, and signs it using
var token=expressjwt.sign({profile}, );
Node Server stores(updates, if user_id exists) the new token in db and sends it as response to client
client stores the new token it received as json data in local-storage
client uses angular-jwt to fetch profile data from the new token and automatically attach the new token in Authorization header for all requests it sends to the server
Now, my questions are:
Do I really need to store the JWT tokens in database? I am certainly not comparing the tokens in request headers with database
Do I need to generate random secret keys for security, each time a person logs in? If yes then how would that fit in both client and server?
When and where do I need to check for token expiration? and How do I refresh it?
I am kind of lost about the design flow and mechanism.
Ad 1. You do not have to store the JWT in the database. User ID can be part of the payload, therefore there's no need for it.
Ad 2. It's a common practice for the server side app to use one secret key for generating all JWT.
Ad 3. Check if token has expired on each request to your API and disallow access if the token has expired, return 401 status code. Client app should prompt user for credentials and request new JWT. If you want to avoid users re-submitting the credentials you can issue a refresh token that later can be used to generate new JWT.
JWT refresh token flow
http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/

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

Token authentication - where to store the token

I am working with PHP and Laravel at the moment, I have a restful api that the user needs to authenticate with to make sure they can only access things they own etc.
What I want to know is where should the token from the server be saved on the client? In a session a cookie? The servers database?
I suggest to go the following route:
the user logs into your site and requests a API usage token
when a new request to your API comes in, compare the token from the incomming request, with the token in the db. if it is found, it's a valid request. the REST client could use the Authorization header to send the token.
send the answer for the request
While the login system of your website, might be session-based with cookies on client-side, the REST API is token-based and doesn't need a cookie or session.
Please take a look at this for more details:
https://softwareengineering.stackexchange.com/a/141434/111803

Authentication model for Android application

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.

Categories