Authentication : Facebook user access token validation on server side? - android

A lot of questions here are talking about validation process of Facebook access token on the server side. I am bit confused how is still secure?
My client and server flows are:
User Continue with Facebook using Mobile SDK on the client side.
Facebook returns User access token to the client side.
Server endpoints receive user access token (via POST method) and validate the access_token using Graph API.
In case of authenticated user return the JWT authorization token in response
In the meantime (within an hour), If hackers find out the endpoint and pass the new access_token to the hacked endpoint.
What will happen if 5th point gets executed? It's difficult to hack the POST parameters but it might be possible after decompiling the app and see the classes file (At least for android apk). In this case, Server will not recognize the forged request and will always return the JWT Authorization token to make further calls.
The validity of Facebook access_token is 60 days. Do I need to provide an extra layer of security at the time of validation endpoint to make sure that the request is only coming from the application?
Is facebook user access_token always changing whenever a user is requesting to sign in?
Any kind of help would be appreciable. Thanks

Solution:
Generated access_token will always belongs to an App. To verify it pass the access_token and app_tokenin:
https://graph.facebook.com/debug_token?
access_token=ACCESS_TOKEN
&app_token=APP_TOKEN

Related

Use 2 different login methods: JWT token and Google sign-in in one app

I have an application that is on the client side: android app, and on the server side: flask based rest api, login with JWT token.
For better security, I want to combine login with Google as well.
The problem is:
The naive solution, is on the client side:
I need to "SPLIT" the login code for the 2 cases - That's not so bad,
But later on for each request to the server - I need to check if I have jwt token, or google user data, and send the correct call.
Then on the server side as well - I need to "SPLIT" my code at every part of the Api to check weather it had jwt token or Google user.
This naive solution seems ugly to me, and i'm asking if there is a better approach to this problem.
My friend suggested me to drop the jwt connecting and use only google, but from the user's side, I think it's better to have the 2 as options and to choose from.
A straight-forward answer: Why don't you give the user a JWT token after they've logged in with Google? How we usually do this is: Login on client -> Send Google token -> Server verifies and sends JWT token -> User uses JWT Token and server uses Google token for updating the user information like the profile image or name.

Secure account creation on a server after using Facebook LoginButton in a mobile app

I would like to create an app in which there is a mobile (Android) client which uses REST API from the server. A user has to login with Facebook account (using Facebook SDK's LoginButton); on success this should create a user account on the server at the first log in.
I've already read a lot of tutorials about how to secure HTTP API using SSL and access tokens, but there is one point which I don't get. The flow should look like this:
a user log in on the Android app with the Facebook LoginButton
in the Android app I receive an access token on successful log in which I can push to the server
I can validate this access token against Graph API
if validation in 3. is succesful I can create a user account on the server
all other calls to my server API can be secured with received access token or other token which would be created by me
but what about the 2. point? I have to expose API call which takes an access token and creates an account. This API call won't be secured, so if someone calls it with stolen/properly fabricated access token, then I will create an account which shouldn't exist. How to solve this? Do I have to assume that if my create account API is called with an access token which is valid (because I validate it in 3.) then everything is ok? Is there a better solution?
You are right, never trust the client. Always validate all client input again on the server.
In your case, you're validation of the token on the server in Step 3 should include comparing the result from Graph API with the result from decrypting the user info from the token. If both match, then proceed.
There are several code examples on Facebook website on how to do this correctly. They are available in several server languages (e.g. PHP) so I recommend reviewing them.

Understanding the Google Sign-in flow with token validation

In my Android app I want the users to be able to exchange messages.
To authenticate the users I want to use the Google+ Sign-in for Android provided by the Google Play Services. The flow currently looks like this:
First run: Display "Sign-in with Google" button.
The user clicks on the button and grants permission.
The user enters a message and sends it. In the background I request a token (ya29...) with GoogleAuthUtil.getTokenWithNotification(...), attach the token to the message and send it to the server (HTTPS POST).
On the server side I receive the message+token and call the tokeninfo endpoint. Then I validate the audience field. If everything looks good I grab the user_id from the tokeninfo endpoint and forward the message to the recipient.
My questions are:
Is this flow correct, or am I missing something?
Do I really have to call GoogleAuthUtil.getTokenWithNotification(...) for every single message?
Do I really have to validate the token with the tokeninfo endpoint every time?
This is the first time I'm using this API and OAuth in general, so I'm not quite sure if I understood the concept completely.
Is this flow correct, or am I missing something?
So far everything is right. But I would recommend another approach on the server side. You do not need to do a HTTP request to Google (and parse the JSON afterwards), you can simply use a library from Google for that. Take a look at the bottom of Using OAuth 2.0.
Using code from Verifying Back-End Calls from Android Apps
you can do this:
Checker checker = new Checker();
GoogleIdToken.Payload payload = checker.check(token);
String mail = payload.getEmail();
Do I really have to call GoogleAuthUtil.getTokenWithNotification(...) for every single message?
No, you don't. The token is valid for some time (I think it was one hour). Therefore store the token in your app and send it to server. If the authorization fails on server side, because the token is expired, you can return HTTP 401 (unauthorized) and your app knows that it has to generate a new token.
Do I really have to validate the token with the tokeninfo endpoint every time?
Of course you have to validate the token. You have to prevent that requests are faked. If you only accept valid tokens it is more complicated to send wrong data to your server.

Using Device to authenticate a HTTP request

I'm trying to authenticate a HTTP request using a token sent by an Android application, but I have no idea how to do this.
To get this token I must to send an user a password, to my ruby application that returns the token, but I want to know how to verify all requests from my android application using this token.
I know the "before_filter" on ruby, but I think that it could have problems with my first authentication, because I have to login with the user and password just once, but every time with the token.
If you can indicate any links or some pieces of code ...
Thanks in advance.
After successful log-in you should save Token in Constants and should send this token with each HTTP request.Server will verify user with access token and return result.

How to put user authentication into a mobile application

I'm interested in the best way to do user auth in a mobile app. At the moment the set up is quite simple. I'm storing the username and password on the app and sending it to the api each time I need to run a restricted query.
This I feel is probably the wrong way to go about this.
Would a better way to be to send the username and password when the user logs in and then store that user's id? The problem with this is that then the api accepts a user id and not a username and password. A user id will be much easier to "guess" at and malicious persons would be able to submit a req to the api with randomly selected user id's performing actions under their account. I have an api key. Is this secure enough?
The issue is that I want to start integrating twitter and facebook oauth into the app. I haven't read much about it, but I think you get a "token". How would this work with the set up that you're suggesting? Would there be benefit to creating a token in my own database of users and using the token (whether it be mine, facebook's or twitter's) as the authorisation? Or would it make sense to keep each service separate and deal with them separately?
Thank you.
The correct way would be to generate auth token on the server when user logs and send this token in login reply. Then this token is used in subsequent requests.
This means that server must keep track of auth tokens it generates. You can also track token creation times and make tokens expire after some time.
Token must be a sufficiently long random string, so that it can not be easily guessed. How to do this was answered before: How to generate a random alpha-numeric string?
Personally I prefer the UUID approach.
Update:
This problem was already solved in web browsers, via cookies and sessions. You can reuse this mechanism in your Android requests (though some REST purists disprove this approach):
Enable sessions on server.
When user logs into a server add some data to session, for instance time of login:
request.getSession().setAttribute("timeOfLogin", System.currentTimeMillis());
Since sessions are enabled, you also need to enable support for cookies in your HttpClient requests: Using Cookies across Activities when using HttpClient
Every time a request is made, server should check if session contains timeOfLogin attribute. Otherwise it should return HTTP 401 reply.
When user logs out, call server logout url and clear the cookies on client.

Categories

Resources