I'm working on a mobile app that has both local database and AWS RDS. Data needs to be passed both ways so that user data can be backed up and updated data can be sent to the app. I set up an API to avoid putting database credentials in the app itself. The API triggers code hosted in the cloud to interact with the RDS.
As I understand, Android APK files can be easily hacked. I would like a solution for how to prevent someone from reverse engineering the app's API calls and getting private user data from the RDS. As it is currently, if someone knows how to format an API call they could access data belonging to any user.
You need an API Authorization mechanism. Normally APIs are protected with Authorization Token which is obtained by a successful login. When the user successfully logs in, you should issue the authorization token, Store in device shared preferences that need to be passed with further API calls. I suggest using JWT, simple and available in all major programming languages. Encode the user's unique identifier in JWT token and design your API such a way that the user can only create, read, update, delete based on the identity encoded in JWT. By this, suppose if user token is compromised, that token can be only used to misuse the user-specific data and not all the data in your database.
Consider the given flow for your reference.
Related
Scenario:
I want to create an android app which uses username and password for authentication. I decided to use firebase custom auth for that purpose.
From my android app, I am calling a firebase cloud function to authenticate the user with the provided user credentials.
Firebase gives you complete control over authentication by allowing you to authenticate users or devices using secure JSON Web Tokens (JWTs). You generate these tokens on your server, pass them back to a client device, and then use them to authenticate via the signInWithCustomToken() method.
Source: https://firebase.google.com/docs/auth/admin/create-custom-tokens
I would like to make use of firebase firestore to store username and password and use it to create custom JWT for Firebase custom authentication in firebase cloud functions.
Question:
Should I store user credentials in firebase firestore and if yes, what is the secure way to do so. If no, how should I proceed further?
How to create JWT in firebase cloud functions if the credentials passed to the function match with the credentials in firestore.
Note:
I don't have a credential system or own a server.
If you've never created authentication systems before, I highly recommend finding an existing implementation of such an authentication system for your app. Using something that is made by folks that do this for a living, is much less likely to lead to future data leaks that would negatively affect the users of your app.
That said: if you're going to build your own system, you'll want to have a look at this example usename/auth provider in the functions-samples repo. It shows how to receive the data, how to call a backend system, and how to mint a custom token.
For some information on how to store username/password, see Best way to store password in database. Storing this information in Firestore is a common approach, and no better or worse than storing it in any other properly secured cloud-based database.
I have an Android app that allows users to interact with a third-party service via their API. This API makes use of Basic Authentication, so I need the user's username and password for every API call. Ideally I don't want to store the user's credentials locally as this is very insecure. I don't know much about authentication but this is what I think my ideal solution would be:
The user provides their credentials to this service once for verification
Once verified, I send the user's credentials to a backend service to store them, which gives me an auth token. I store this token locally (is encryption important here?)
Whenever I want to make future calls to this service, I use this auth token to talk to the backend service, which provides me with the user's username/password for Basic Authentication to make API calls
Is this a good solution? If so, are there backend services in place that I can use to facilitate this process? I've looked at Firebase Authentication but I don't know if it fills my needs as I'm trying to store credentials for a third-party service, not specifically for my app. I've heard of Auth0 which may be what I'm looking for but appears to be overkill for a small app like mine.
You can easily use Firebase Auth and get all the functionality you need while keeping your users secure. It provides the features you need:
Firebase supports password authentication and properly stores hashed/salted password credentials according the industry standards. This would be one API to createUserWithEmailAndPassword or signInWithEmailAndPassword.
Firebase provides a mechanism to verify email addresses. It is also one API: user.sendEmailVerification()
On sign in, Firebase Auth returns an ID token (user.getIdToken()) which you can use to identify your users in all authenticated requests. They also provide an Admin SDK to parse and verify that token (auth.verifyIdToken(idToken)). A refresh token is also provided to continuously refresh ID tokens on expiration. This means the sessions are indefinite and the user should not need to sign in again on the device.
The ID token provides additional user data like email_verified which you can use to ensure the user is verified. The ID token is a JWT which can't be compromised without the Firebase Auth backend private key.
I’m implementing a Android app and that must contain a user login. To do this I create my own authenticator with the purpose of login only once. Then AccountManager can request access tokens, so the application is not handling passwords directly. The AccountManager stores the user account and the token.
I’m using JWT (Json Web Token) to authenticate the user in my REST API.
I wonder whether this flow is correct or there is a better approach to do this in Android.
Here is the flow I am currently using:
The user enter user and passwords in the login screen at first time.
I make a request to server to retrieve a valid token (JWT) that is stored in the Account Manager.
Subsequent requests use the received access token until it is expires (1 hour) to retrieve content from the API.
After the token is expired, it can be refreshed up to two weeks after issue time. From this moment, user credentials are needed to retrieve a new token.
Is this process the correct way to work with the token, and refreshing it? Is the process safe? Are there other options?
Considering this flow is not using a “refresh token” to generate a new one but the access token, what would be the best usage of the Android Account Manager? What other tools should I use? Is it recommended an Oauth2 implementation along JWT in order to implement a “refresh token”?
Cheers!
I can tell, you are on the right road of using JSON Web Tokens and reproducing it.
but the safety you mentioned is all about encrypting the token you retrieved and then saving it in Account Manager (also the same with user credentials) with some encryption method of your choice like AES or RSA and then decrypt if when you wish to use. Also using a server-generated secret key with a secret algorithm would kill the shot for any hacker.
As you understand everyone with a root access can get hands on the saved credentials database and use it.
Using these tricks will lower the need of using Oauth 2.0 which involves a refresh token.
hope it helps
Here is the idea:
There is an android application that will consume services that I will create using Spring. However, this services should have some sort of security, so only people logged in on my android app can consume such services.
On my android app, I will use Firebase to do the authentication, using email and password. So, there will be no need for me to configure any server to make this control. (Like Spring OAuth2)
The question is, once the user is logged on my app and wants to consume some service, for example GET LIST of something, that I will provide on the Server using Spring, how can I check if the user is logged on the app, so I can grant access to that service?
Your Android app will need to pass the user's token on to your app server, where you can then verify that the id token is valid and use the information in it.
See the Firebase documentation on verifying id tokens for full information, including this description:
If your Firebase client app communicates with a custom backend server, you might need to identify the currently signed-in user on that server. To do so securely, after a successful sign-in, send the user's ID token to your server using HTTPS. Then, on the server, verify the integrity and authenticity of the ID token and retrieve the uid from it. You can use the uid transmitted in this way to securely identify the currently signed-in user on your server.
Also note this first note in blue:
Note: Many use cases for verifying ID tokens on the server can be accomplished by using Security Rules for the Firebase Realtime Database and Firebase Storage. See if those solve your problem before verifying ID tokens yourself.
While it might not apply for your use-case, always keep it in mind since the most maintainable code is the code that you didn't have to write. :-)
Let's say I have this application developed for Android which needs to use a Facebook (or Twitter or Google or all of them) based authentication so it can access this private API I've developed with nodejs' Express for example (could be any other platform too). I've read this answer here that gave me a hint on how to associate my authentication model with my user model (and another one here that made me realize those two parts are different), Facebook authenticates and I use some information they provide to create an "identity" for this user, but what exactly is this information that will create a link between the user and the identity? no abstract terms please, do I need to use and send either the access token or the Facebook user id? or would I just send the access token and let the server get the user id?
Regarding new requests after this user has been authenticated, I've read about API keys of some sort, which are basically some random strings that I should add to my identities (or users? this part confuses me) entities, and they should be securely stored in the mobile device as a mechanism to authenticate further requests, but how do I securely get this random string to the device in the first place? am I misunderstanding the way API keys work? are Facebook authentication and API keys mutually exclusive? if so, what would I use for further requests just using a provider for my authentication? it seems illogical to pass the access code in every request, even more so passing the user id.
The focus of this question is for me model a solid strategy for managing this authentication-user-identity behavior, would love any insights on how has this been done before since the material I've found in SO and the web has been very lacking, often referring just to server side implementations or just authentication answers, not addressing the issue of further requests.
The Facebook/User ID is there to identify the (returning) User. Keep in mind that you only get an "App Scoped ID", not the "real" ID - it will be unique in the App, but different in another one. See changelog: https://developers.facebook.com/docs/apps/changelog
Access Tokens are there to make calls to the Graph API. There are 3 different Tokens (App Token, User Token, Page Token), you can read more about them in those articles:
https://developers.facebook.com/docs/facebook-login/access-tokens/
http://www.devils-heaven.com/facebook-access-tokens/
You can store Access Tokens for later, but in most cases you don´t need to store them - only if you need to access the API while the User is not using your App.
In general, App Tokens can be used to request public stuff and to change App settings. User Tokens can be used to request (or post) User stuff and Page Tokens can be used to request insights of a Facebook Page and other things.
If you want to deal with Access Tokens on your own, make sure to activate appsecret_proof in the settings. I suggest reading this article about securing API calls: https://developers.facebook.com/docs/graph-api/securing-requests