OAUTH and iOS app best practices: leave user logged in? - ios

I am working on my own app that uses instagram; but I think that this question is generalizable:
If my app determines that there is no auth token and requires the user to login; what should be done by the app in the way of cleanup after its done?
does it : leave the user "logged in" and let it be the responsibility of the user to invalidate the token ?
or: should the app basically leave things at the same base state as it found it? Going along with this reasoning; then it would require the app to keep track of weather it logged the user in or were they already logged in " valid authorization token" before the app was run ?
thanks

You need to implement a renew mechanism for your token.
Basically check that the token is still valid, otherwise delete it and unlog the user.
To unlog, simple, just delete the token (and user related datas).
If your app requires for the user to be logged in then you can just check if there is a token before displaying the related view.
Your user is unaware of the token (and everything related to it) and that needs to stay this way, period. If the token needs to be invalidated at some point, your app needs to handle it.

Related

Dropbox OAuth2 API always prompts user for permission when a refresh token is requested

I'm writing an offline application that uses the Dropbox API. When a user comes to the application, I'm using the https://api.dropbox.com/oauth2/token (docs) to get a refresh_token, which I store for later use.
I am calling the same endpoint every time the user logs in (unless I've already got the user's data in a cookie). I'm not sure that this is the best way to go about it: I at least need to get the user's account_id, so that I can look up their refresh_token in the database if I already have it. But every time I call https://api.dropbox.com/oauth2/token, the user is redirected to the Dropbox app authorization interface, as if they've never approved the app before.
So I would either like to know how to stop Dropbox from forcing the user to re-authorize an app every time. Or, if that is just how https://api.dropbox.com/oauth2/token is supposed to work, I'd instead like to be able to get their account_id somehow when they visit my page.
(In case it's relevant, the app is still in development mode at this point.)
The https://api.dropbox.com/oauth2/token endpoint is an OAuth endpoint that the app can call to get an access token/refresh token. Being an API endpoint, it does not itself redirect the user to the Dropbox app authorization page.
The Dropbox app authorization page is at https://www.dropbox.com/oauth2/authorize (documented here), and the app decides if/when to direct the user there to authorize the app.
You generally only need to send the user through the app authorization flow (sending them to https://www.dropbox.com/oauth2/authorize and then calling https://api.dropbox.com/oauth2/token) once per user for an "offline" application. Once you do so, you should store the resulting refresh token for that user. You'll typically store the refresh token for that user tied to their user account in your own app.
Exactly how you manage the user accounts in your own app will depend on how it's built, but, as it sounds like this is a web app, typically you would use the user's browser cookies to identify the user when they return to your page so that you can look them up in your database and retrieve their details, such as their corresponding refresh token. (Or, if they're not already signed in to your web app, you would have them do so first.)
Greg's answer is very helpful, and very politely addresses my misunderstanding of the auth flow. (I was revisiting old code I'd written years previously—obviously I should have documented it better than I had!)
In the end I believe that Dropbox was forcing me to reauthorize because my application was in development mode, and had a small user base. When I used the identical code in an app set to production mode, it stopped forcing me to reauthorize. So the “problem” is really a Dropbox security feature, and the solution was just to use production mode.

Reauthenticating logged in user after extended period of time

I'm using firebase authentication for my app and I have the users sign up, login, and log out all set up and going. However, I'm a little confused on how to manage the state of the users login status. Currently, if a user is logged into the app, but doesn't use the app for an extended period of time, firebase doesn't recognize them as logged in. I'm looking at the documentation and the approach is a bit unclear.
Should I be storing a FIRAuthCredential every time the user logs in, and then call reauthenticateWithCredential using that credential?
Firebase Auth only requires recent sign-in for sensitive operations like: deleting a user, changing a user's email or password. These are for obvious reasons. You want to make sure it is the same user before making such sensitive changes. Otherwise, the user is considered signed in indefinitely by the Firebase Auth backend (your assumption that "firebase doesn't recognize them as logged in" is not correct). Of course, a developer may also require re-auth before other operations like updating credit card, shipping address, etc. A developer would check the auth_time on the Firebase ID token. Only in such cases would you re-auth. You should never store credentials such as password on the client to avoid prompting the user to reauthenticate. It is needed to protect the user's account.
yes I think that is going to be right approach or second approach you can try is like when a user press login button instead of directly calling Authenticate User put a check in which last login timestamp value will be stored when user login compare timestamp value and then perform selected operation as you want . NOTE - you will be required to check weather user exist or not , but I think first approach will be better as if you had noticed in many Social apps like kik it ask for reauthentication after a long period of time but first it authenticate user instead of displaying home screen it take to reAuthenticate screen

Desire2Learn Revoking User Keys

I am unable to revoke application access by a user via either a password reset or by explicitly clearing app keys in user management. The latter method gives a reply indicating that access has been revoked, but when the user hits the tool, they are not re-prompted to approve access to their information.
There are number of possibilities here:
It's possible that there is latency between the declared revocation of keys and the cleanup task that goes through the database and actually cleans them up; I believe that at one point, such a latency existed, was identified, and fixed through service packs and subsequent releases. Accordingly, you may address this issue by ensuring that your back-end service is up-to-date with its available service packs.
It's possible that what's being revoked is the keys, and the necessity to authenticate to rebuild keys, but not the confirmation step that would appear to the user asking for access permission (assuming the user once authenticated, and checked the "don't prompt me to ask for permission again") dialog.
Can you confirm if the request for user tokens by the client application actually does get back tokens? Or is it just that the authentication step happens with no notice of client confirmation to access?
Note that the re-authentication might appear to happen silently; if the client application's request for user tokens happens through a user's browser context where the back-end service can determine that the user is already logged in to the LMS, then the request for tokens could succeed automatically:
The user is assumed to have already authenticated in order to have an active web session, so there's no need to re-gather a username/password (or whatever user auth step the LMS uses) to re-confirm identity.
The user may already have confirmed access for the application and dismissed the confirmation step with "don't ask me again". If the user has confirmed access with "don't ask me again" this choice will get remembered, even if the user tokens get expired due to password change or access revocation by an admin.
If you explicitly log a user out of their LMS session, and then test the client app, this should indicate to you visibly whether the re-authentication step is actually taking place (the user's browser will then get directed to the login process for the back-end service).
Note that, although a user password change or access revocation by an admin can remove the recorded user Id/Key pair associated with an application, it does not remove the record of the confirmation form having been dismissed with "don't ask again". Currently our system does not expose a way to reset that confirmation state.
If after considering these points you feel you still have an issue, I would encourage you to open a support incident through your organization's approved support contact, or your account or partner manager. Desire2Learn takes security related reports quite seriously, and if you've uncovered an issue that hasn't yet been addressed, I would encourage you to report it as a defect.

Soundcloud as Oauth Provider: How to make it connect only one time

I'm currently implementing an Oauth consumer service which is going to use Soundcloud as an Oauth service provider as well. But I'm having the following issue with it: Taking Facebook or Twitter example, you go there, you sign in, you fill up the permission form, and you are redirected back to your app. If you go there a second time, and given you are already sign in, you basically skip all steps and are redirected back instantly. That means, Facebook recognized that you already gave permission to that 3rd party service, so it doesn't ask your permission constantly.
And that's what's happening when I use Soundcloud. Basically everytime I redirected the user to the Soundcloud Oauth connect endpoint, the permission form always shows up, even though I already gave permission to that 3rd party service previously. I'm forced to press "connect" every single time, which is a drag from the user perspective (how many times can you give permission to the same entity). My question is: is there a parameter I can use to make soundcloud recognize/validate the previous permission from the user account to that specific 3rd party service? Or is this Soundcloud Oauth design implementation and we have to live with it?
Edit:
Maybe this wasn't clear, but each time I press "connect" in soundcloud, a new access token is being generated and delivered. Since my app uses this access token to identify its users, it doesn't work very well for me that the access token is getting updated everytime I want to log in, making me effectively "sign up" everytime. To sum it up, I want to get the previously attributed token to my account, so I can look up in my database, identify it and log him in.
I'm also looking for a solution which doesn't involve storing state in the client that might get cleaned up.
What you can do is store the user's oauth token in local storage and reuse it in future sessions. That's what happens on soundcloud.com.
A longer explanation:
When you use the Connect flow, the user is authenticated by SoundCloud (either by using username/password, Facebook Connect, or an already-existing session on soundcloud.com), and then when it is successful, your app is given an oauth token for that user. This is passed to the callback page which is registered for your app.
That token is the only piece of information needed to have the user be "logged in". Unless the token expires (by time, or by the user manually revoking it), then you can reuse that in future sessions.
I think I'm a bit confused about your application's design: where and how is the oauth token being used? I think that instead of using the token as an identifier, perhaps the user's permalink might be better? If you have the oauth token, you can find out the permalink by querying api.soundcloud.com/me.

omniauth - is there any reason why I should store the OAuth2 token in db?

So, I'm just starting to use omniauth and have gotten it working with facebook. I have set it up so that it automatically redirects back to facebook for a new token when the current token expires. Based upon that, is there any reason why I should be storing the token to the db? I currently log user accesses but don't really see any value in logging the token. Would appreciate any ideas on why I should.
thx
Depends on your business logic. For example, do you need to access the user's Facebook details at a later time, even when he is logged out? Or if you are queuing tasks (i.e. running this in the background), do you need to post to his wall a few hours later, instead of this very instant?
Another reason I can think of, is. Do you require your app to obtain a new token via Facebook all the time when the user needs to interact to Facebook via your app? Or would you like to store these tokens in your app, so the user does not need to go through the same process over and over?
It all depends on the kind of user experience you are trying to deliver.

Resources