swift: auto logout after certain time - ios

I am developing an app which is connected to a server through .net api.
What user logs in it generate an access token which is used to make network calls.
Requirement: After 20 mins of the generation of that access token, the
token gets expired and the user have to log in again to continue using
the app.
How can I achieve this feature that after 20 min the user will get logout from app and redirected to the home page.
If the user is using app even after 20 min from login? how to save the access token in app and remove it once user logout.
I have seen a couple of answers in Objective c but I want the answer in swift.

Save your access token to the keychain, and timestamp it.
Write a function which gets you the API token from the keychain. Each time this function accesses the access token, it should check if its timestamp is older than 20 mins it should return nil, and then you shoudl take the user to the home screen.

Welcome to stack overflow
Short Answer
Create a timer in app delegate to track the token expiry. And reset timer when needed.
Long Answer TLDR;
To implement the feature as you have explained we need to
Keep track of access token expiry in app delegate only.
Start a timer for 20 mins when user logs in from AppDelegate.
Before making any API Calls access the token from app delegate (Internally you can save in any secure method for example KeyChain),
While accessing token from app Delegate check if timer is expired. If so present your login screen in the window.
If not present then make API Call and let the user do the tasks.
Advantage of this method
If you are sure that access token will expire in 20mins then without making any API calls we can logout the user from app.

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.

How can I get access token with refresh token automatically for iOS/swift?(every hour)

Now I'm connecting my iOS app with server.
For use the server in the app, the app need Access Token.
When user logs in, they get Access Token with Refresh Token.
So after logged in, users don't need to log in anymore. And users can use the app without logging like instagram or facebook.
But the app must update/renew access token by using refresh token every hour,
because access token expires in 3600seconds(1hour).
But how can I query/update refresh token/access token every hour?
I think the app do this every hour automatically even in background.
now I can get access token using Alamofire.
But I'm not used to use connect server with app.
My app is for iOS and coded with Swift.
When the app is first opened by the user (comes to the foreground) you can refresh, then start a timer, say for 55 minutes. When the timer expires you can refresh. When the application goes to the background destroy the timer. Don't expect that the application should run a refresh in the background, it shouldn't and it has no reason to.
The above is all you need to do. When the app comes to the foreground you can instead check how much longer your current token is valid for and decide to not refresh and start a timer for N-5 minutes instead. And you can think about how to deal with refresh failures and no internet connection by changing the timer to run each minute perhaps...

How to make to manage token refresh in app ios

I have a web site where I have built a API Rest for IOS app. The app is composed from a Tab bar with two views the first view show the view of WELCOME or LIST OF EVENTS it depends on if user is logged or no, and the second view show the LOGINVIEW. I have built the method on server that check if the token is valid yet in the time so that if the user has already made the login in the app, when the token will expire, I would like that the app would has to do a refresh token (by call to the server tokenIsAlive the response NO and it would make autoLogin in background) using the credential saved in the NSUserdefault in the device. But I would like that the refresh token would has to be hidden (background) so that the app can show the views where require the authenticated user. I have used AFNetworking but how can I make to refresh token hidden? Which way would be advised to check if the token is not expire?
Does it to do for each call (getEvent,getListEvents,updateEvent..ecc) to the server, or only into the method
(void)applicationDidBecomeActive:(UIApplication *)application
?
The easiest approach is to set an NSTimer to call a method that does the refreshing after a set time interval (depending on the expiry time of the token). Also, set the timer's repeat property to TRUE. This way, the token remains fresh and does not expire unless the user logs out. When the user logs out,make sure you invalidate the timer and stop refreshing the token.

Obtain NEW Apple device token?

I am creating an app that allows the user to log out of the app and log in as different user if they want to. Is there any way to obtain a new device token from Apple once the new user logs in? Is there a way to force call the didRegisterForRemoteNotificationsWithDeviceToken method?
No, you can't request a new device token. They expire from time to time, and only then will you get a new one (or if you have a different app with a different bundle id, the token will be different).
Create a function to handle didRegister and call that from didRegisterForRemoteNotificationsWithDeviceToken. Then use that function when you need to force the call.
Since users are logging in, pass the information with the device token to the server every time someone logs in and associate the user to the token on the server side.
There is no way to get a different device token. You need to remove the token from the backend when the user logs out.
I'm not sure how it behaves in iOS7 and later, but prior to iOS7, all applications on the same device would get the same device token, and therefore what you ask is impossible. As of iOS7, each application gets its own device token, but I'm not sure if that token can change on consecutive registrations.
You can always force call the didRegisterForRemoteNotificationsWithDeviceToken by calling registerForRemoteNotificationTypes, but usually you'll get the same device token.
If the goal is to associate notifications with specific users, then as of iOS 10, you can try implementing a NotificationService extension to filter only those notifications associated with the currently authenticated user. While multiple users on the same device will be associated with the same device token at the server, the client will only display notifications for the current user - assuming that only one user at a time can be logged-in.
This approach also allows for having notifications that don't require authentication - just pass those through unaltered.
As mentioned above, you can force a request-response token update after user login by explicitly calling UIApplication.shared.registerForRemoteNotification (Swift 3+). Then send that user+device token combination to your application server for use.

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.

Resources