How to handle JWT expiry mechanism in native apps - android

I am building a hybrid app on React Native, We are using Django rest framework on the backend. We are using JWT for securing the app, the use case of the app involves storing sensitive information.
The problem is in JWT expiry. I need to hit an API with the accessToken to get a new token, this works fine and token won't expire if the user opens app every day, which is next to impossible.
Hence the user logs out every few days since by the time he opens the app the token is expired. Is there a better way to handle this? Facebook app, google pay app never log out the user.
I tried keeping a variable associated with a user suggesting he is a mobile app user and thus never expiring that token unless he logs out or done so explicitly, but I've had reviews that's a dangerous method.

You should not use access_token to get a new one!
The proper way is to give a refresh_token to the user each time you issue an access_token.
refresh_token is a long-lived one-time use token which is used to get a new access_token.
You can search to learn more about refresh_token.

Related

Handling Oath 2.0 Authorization from Backend Job

I am trying to find a solution to the following:
Requirments
There is exists an app that allows users to add integration providers
These integration providers use oath 2.0 authorization to secure their data
The app needs the ability to have a backend job fetch data on-behalf of the user once per day
The data fetched is ingested and merged into a report that is compiled on the app for the user
Problem
User Delegated Access Token from Backend Job - I'm having trouble finding the solution that allows me to have a valid access token that is on behalf of the user without having to generate the access token from the app side
What I have tried
Refresh Token - I have tried the approach of using the refresh token to constantly get a new access token but this solution is fragile in the sense that there might be a situation that a new token is not generated in time or for some reason the user still needs to reauthenticate the connection to the provider
Automated Browser Flows - I have tried automating the user's authentication flow from the backend using saved credentials given in the app. This approach is just sketchy, costly, and would require a lot of work on the user agreement side ensuring that is being done on the backend has been consented by the user which essentially reinvents the wheel on user consent which the identity providers should have already been handling
We can use JWT for this. By doing it with JWT we'll create a token and save to the database and on every request it will decrypt the token and get the required data from the token.
Link- https://jwt.io/

Google Sign-In Access Token between backend and client

For a quick project for a hack week me and my team implemented Google Sign-In as registration/authentication for users. The way it works:
User signs in with SDK on client (Android + iOS) and requests access_token
Client receives acces_token and uses that token for each network request to the backend as a query parameter
Our backend does not interact with google services on users behalf
The problem I'm facing is that the provided access_token returned by the google SDK is short-lived (60 minutes). That basically leads me to two questions/problems:
Is the short-living access_token even meant to be used that way?
I am used to another flow where you just use that returned token by google or any other auth provider to authenticate with your backend and then use your own authentication mechanism (probably token based as well).
If I am wrong about 1. then what is a good practise to refresh the token on the client side as it expires every 60 minutes. The way I understand it is that Google SDK starts an activity for result to sign in and I would rather want to handle all the networking in my data layer without context. Do I check the validity of that token before I request the backend every time or do I start some kind of refreshing after I get a 401 response back or something similar?
I am somewhat new in that space and I had quite some discussion about what is right and wrong with the backend guy in our team. I'm thinking number one is right, he says number two. I might be terribly wrong here. Some nice input or resources would be awesome as all the documentation online just don't answer both of those questions.
Do one thing use your google provided access token to generate a new access token in your backend and send this token on login/signup to client. Now your every request will use this token to identify users and keep track of everything.
This will not expire too. I used this in my app and it works flawlessly.

Android Authentication - What is the standard?

I am getting into Android development for the first time and am having a blast, of course. I do have a question, though, about the general approach to authentication (for dealing with a backend).
To begin, here is, in a nut shell, what I have worked out.
Using google's documentation (link), I authenticate the user using the google sign in api. I have put the logic mentioned in the reference in my app's main activity. After the onConnected method fires, I have a successfully connected GoogleApiClient.
With the now connected GoogleApiClient, I use a call to GoogleAuthUtil.getToken to get an oath2 token that I use to authenticate requests to my backend. Basically, any time I make an HTTP request to my backend, I include this token as a header. My backend reads this token and uses the Python API google provides for verifying this token. In the backend, I use the email that is embedded in the (now parsed) token to make sure the user to whom that oauth2 token was issued is, in fact, a user of my system.
Now, here are the questions. First, does this sound like a reasonable approach to authentication on the Android platform? What might I be missing? What could go wrong?
The second question is a bit more direct. When I get the oauth2 token from the client app, I store it and use the same token each time an HTTP request to a secured resource is made. Eventually, of course, the token will expire. From some limited testing using the Android emulator, it seems that if I shut down the application and restart it, I am getting the same, expired token back using the GoogleAuthUtil.getToken, rather than getting a fresh token with a new expiration in the future. In my tests, I have had to restart the emulator in order to get a token with a correct expiry. Am I mistaken here? Is there something special I need to do to tell the Google API to issue me a new token? Do I need to disconnect the GoogleApiClient and reconnect it? I hope to avoid doing this in order to limit the number of activities that need to carry the callbacks required to complete this process.
Any words of wisdom here will be greatly appreciated!
after you have got your token you can use Validate Token, and if it responses with an error: 'invalid_token', you can use GoogleAuth.clearToken(Context context, String token) to clear the token and get a new token with the method you are using to get auth token.

Login with facebook on native android app and send access token to remote server

I'm new to oauth concept. I'm working on an android app which uses facebook login to authenticate. After the authentication is done I want to send the access token to my remote server and make API calls to facebook(api calls from server using access token) and store user information on my server for future use. Is this method preferrable? I came to know that the access token expires after some time. So, Does the user have to login everytime the token expires and I have to send new token to server everytime a new token is cerated?
Any good suggestions on how to implement this are welcomed.
I'm not sure about the latest version of the Facebook SDK as I've not used it, but the previous version has a method "extendAccessTokenIfNeeded" which you could call every time the user runs your app.
Yes process is working with the latest fb api!
You can extend the token for a duration of 60 days (i think), this token you can save on your local database and use that for making user actions on facebook.
the token is bounded to your app and have different grants.
https://developers.facebook.com/docs/opengraph/howtos/publishing-with-app-token/
How to get a Facebook access token for a page with no app or app secret

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