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.
Related
My website has a login feature that lets the user enter their email and password to login to their own account. I now need to have this same functionality brought over to my app.
I have a view already set up with an email and password input field. What I'm confused with is the logic behind logging the user in.
I'm using Retrofit to make calls to my API.
I found this tutorial online, but I'm not sure if this will help me do what I need:
https://futurestud.io/tutorials/android-basic-authentication-with-retrofit
I also found this tutorial (for token authentication), so now I'm doubly confused as to whether or not either of these will help me or if they're for something else:
https://futurestud.io/tutorials/retrofit-token-authentication-on-android
So my question is, using Retrofit, how do I authenticate a user login, and upon successful authentication, how can I make later calls to my API using the user ID (from the database)?
Use token based authentication. When you login, the server sends you a random token and stores it in its db. You save that random token. In all future calls, you pass up that random token. The server checks the token before processing each call. Remember to use HTTPS so that your data is encrypted in transit.
Why is this better than storing username and password? First, you can easily revoke the token server side. Secondly, if the user reuses his password on multiple sites then he hasn't just compromised one account, he's compromised all of them. With a token he has at worst compromised this account.
I have a background in web development but I am very new to the mobile world. So, I'm not sure how to proceed with this situation:
The user login in the app
The credentials are sent to the server through a POST request.
If the response is ok, it redirects to the main activity.
Now, I want to know if I have to keep the user's ID or not. I know that when we are using a browser the server saves a "session" so the client doesn't need to send the ID everytime to request data. Is that also true with mobile apps (Android)?
By the way, I'm also responsible for building the REST API but don't have any experience targeting mobile devices.
Big question to answer, and it depends and not sure what server technology you are using. However I can describe an approach I implemented (.Net background).
It seems you are writing a mobile app?
The mobile app would first make an authentication call passing id and password to your login api, over https of course. Often the url would be something like
//yourwebsite/Account/Token
Your api would validate the user and if ok, issue a bearer token.
The mobile app needs to remember this token and on subsequent calls pass this in the request header. That's how the server will know who this is. You don't need to send the user id and password any more. And there may be a strong security argument for not storing the user id and password on the mobile device at all.
Now, your server code will validate the token, and you will know who and what the user can do. The token typically expires, so any mobile client needs to check for this and re-authenticate to get a fresh token.
But how will the server know this token, who it belongs to?
In an MVC world for example, there's framework code to help here. There's plenty of MVC template code. If you happen to be developing .Net api services, see this http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api
If you are not .Net on the server, I'm sure there will be something else to help you along the same principals.
As for developing RESTful API's, ServiceStack is seriously worth considering. If too expensive, at least consider their approach and roll your own (especially when it comes to versioning of your api's).
You misunderstand the case with browsers, therefore your conclusion is flawed. Let me explain: When you log in to a website using a web-browser, a session is saved indeed, but not only on the server. It is saved at the client-side as well. Whenever you send a request from there on to the server, you have to send that stored information as well, called cookie to identify yourself.
Let's think about this more deeply: How would a server identify your session as being your session without getting a cookie? By IP address? Nope, the IP address can be used by many and it might change. By browser session? Yes, by browser session, which includes the cookie as well.
Now that you understand that the session is saved by both the server and the client, you surely already know that you need the very same for mobile apps as well. The client logs in, therefore a cookie is generated for the client. This should be difficult to guess. From there on, the client uses the server using the cookie created for it.
If you do not believe me, visit a website where you are not logged in, and then run console.log(document.cookie);, log in, then run console.log(document.cookie) again, then log out andd run console.log(document.cookie) again.
We have a working website and now developing android application. Some API calls are public however some api calls requires valid user. One server side it is being maintained through sessions and cookies. How can I communicate with server securely from app. I want that user login once until user press logout or uninstall the app. I don't want to store user username and password in app because it can be easily access by anyone if device is rooted and also I don't have password if user is using facebook login method. What should I do to in app and on server side to make it secure and easy. I think apps like facebook etc use those type of approaches in their apps which I am searching.
I have done research on this and found only that I should use static HttpClient.
I am using volley library for network calls because it suites me.
You use a token. When the user logs in (over an HTTPS webservice), he sends up his username and password. The server stores that in a database and returns a token, just like a cookie would. All future requests from the app to the webservice should be done over HTTPS and should have that token as one of the parameters. The server can then lookup who it assigned that token to in its database, and send the user the appropriate data. If the token isn't there or isn't in the db, you return an error. When the user logs out, you delete the token from the DB.
The token number space needs to be big enough that a random token can't be guessed. Using a second piece of data on each request (such as user name, or something identifying the phone such as ANDROID_ID) would help prevent guessing attacks. And of course if you get repeated requests from someone with bad tokens you should treat that as an attack, just like you would with bad cookies.
I have an Android app that connects to a .Net api for receiving/setting data. The confusion that I have is regarding how to signup/login the user first time and authenticate it every time he makes a request to the api.
If I just use username/password based authentication would that be
safe enough? And should I save that username/password in the device
for every api request to the server authenticate him and then serve
his request?
Should I issue a GUID for every user at the signup, save it in
their device and retrieve every time during an api request?
What other patterns are available and which are most efficient and secure.
First important note - don't store passwords anywhere - in your DB store it hashed and not in plain text.
In general, you want a flow where you create a session for the user and use that on
subsequent requests. So, when your user logs in you validate the user/password hash combination and issue a session for the user. In your application you store the session and use it on future requests, until the user logs out or the session expires (usually you set an expiration to sessions).
There are also some generic auth flows you can look at, like oauth2.
I also strongly suggest going throw some documentation on authentication flows best practices.
You can start with these:
https://www.owasp.org/index.php/Authentication_Cheat_Sheet
http://codingkilledthecat.wordpress.com/2012/09/04/some-best-practices-for-web-app-authentication/
I'm trying Google Plus sign-in in an Android app (with backend support).
I could get access token and email from the user, but know I don't know how should I recognise this user from the server. I'm sending this to the server (email and oauth token) with a POST throught SSL
Of course I could recognise them with their email, but that would open the doors for everyone how knows another email that's on the database.
How could I verify that the user's correctly authenticated and has sent me the correct oauth token for this email?
Thanks!
Two thoughts:
1) Generally, you shouldn't be sending the auth token over the wire if you can help it. Instead you should be using a hybrid flow where the client gets a one time code when it authenticates, passes you this one time code, and you can redeem this for an auth token and a refresh token. Using this method, your server also has offline access on behalf of the user. See https://developers.google.com/+/web/signin/server-side-flow for details. However, I'm not entirely sure how this works with the Android library.
2) Regardless of (1), generally what you can do is to use the plus.people.get method on the server with the userID of "me" to get the user's userID and verify this against what you're expecting. See https://developers.google.com/+/api/latest/people/get for more details.
Yours is a perfect case to use the Authorization code flow.
See this link. It has some workflow diagrams that you might want to see. In your case the user should authenticate and receive an authorization code (and not a token!).
He would then send the authorization code to your server, you can exchange this code for access + refresh tokens. Have your client registered for the scope and have the client credentials.
The access token flow (called the implicit grant flow) is generally used when requests need to be sent directly from the user's browser.
And, as #Prisoner already mentioned, you will have offline access too. That would be a much better design.
EDIT - you might also want to take a look at What is the difference between the 2 workflows? When to use Authorization Code flow?