Expired FB Token - ios

I currently develop an iOS app that uses FB Connect to enable login. In the past 2 months, I have gotten at least two reports of users who are unable to login to our app. It turns out the solution was for them to go to Settings->Facebook, click on their account and relogin. I'm guessing the access token is expiring for some users.
Why is the iOS system level token not automatically refreshing when needed? Is there some way for my app to initiate this? Or at least some way to alert a user to this case so they can fix it themselves?
And why aren't more people seeing this?
Thanks!

I guess you have to handle this in your app yourself. Have a look at https://developers.facebook.com/docs/ios/errors#auth and check the login error scenarios. There's also some sample code included.
Also, you could have a look here: https://developers.facebook.com/docs/facebook-login/ios/v2.0#sessions

Related

SFAuthenticationSession/ASWebAuthenticationSession and logging out

I'm planning to switch an app from the old OAuth flow with the SFSafariViewController to the new flow with iOS 11's SFAuthenticationSession. Logging in isn't an issue, the transfer to the new API took me a few minutes to implement. However logging out has me baffled.
How?
I can't find any mentioning of wanting to offer the option of logging out anywhere in the docs. Using the old SFSafariViewController to invalidate the cookies? Nope, they're not shared anymore with SFAuthenticationSession. As soon as I restart the authentication session the user get's logged in automatically and there's no way out. So how to enable logging out? Or am I simply overlooking something completely obvious?
Update:
I found a "way that works" in a technical sense, but it's bonkers for the user: Open a new SFAuthenticationSession on the logout page that clears the cookie. But that means when logging out the alert view asks the user again whether he'd like to log in via the service. If yes is selected ("logging in"), the cookie clearing logout page is opened, the user has to manually dismiss the view, which can be caught by the completion handler and we know we can open the login view again.. displaying the login prompt to log out? I really don't like this solution.
Any ideas? Am I still overlooking a completely obvious solution?
Update 2: As no one has any clue about this issue so far, this is probably not an easy one. I have filed a suggestion with Apple via their report tool to either clarify how to handle this or build it into the API if not available. Will post if I get an answer.
Update 3: After pondering the issue a bit more we found another possible (although also unattractive) solution if you can influence the login page of the OAuth provider: make cookies very short lived. Then the login page can be opened without automatic log in. However this kills the whole purpose of sharing login sessions between apps.. and you need to be able to influence the login page.
Update 4: Since iOS 12 SFAuthenticationSession is deprecated and got replaced by ASWebAuthenticationSession. However ASWebAuthenticationSession does not change anything in regard to logging out. It's still not possible. Same issue as before.
With ASWebAuthenticationSession, setting .prefersEphemeralWebBrowserSession to true prior to calling .start() will force the user to enter credentials in the browser session. While not the same as logging out, this will allow a new user to login with different credentials when launching the next session.
Update November 2020: We used #react-native-community/cookies to clear cookies as a workaround. See the snipped below as an example.
import CookieManager from '#react-native-community/cookies';
CookieManager.clearAll().catch(e => alert("Error deleting cookies during logout"))
Previous answer from April 2020. This may be helpful for anybody struggling with this. I've spent few hours testing different options, going through apps and looking how they do it and reading forums/discussions.
I haven't find a way to programatically clear cookies and there is no documentation on Apple on this.
Using FB as an example. Logging out from Safari and deleting FB app doesn't help. Any app which is downloaded will not ask for login to FB if you logged in once before through ASWebAuthenticationSession or SFAuthenticationSession.
If users ask how to force login (even though it's not your problem as a developer) you can point them to: Settings -> Safari -> Advanced -> Website Data -> Remove All Website Data (or just the ones for the provider).
If your use case needs switching of users (like in my case where we use Azure AD and users share 1 phone) you have 2 options. A) Open ASWebAuthenticationSession with the logout endpoint (as mentioned, this is very weird UX). B) Open Safari as a separate app (not inside yours) and do login/logout there. Unfortunately, there is no way to redirect the user to your app after logout if the OAuth provider doesn't support redirect on logout.
It sucks because this prevents developers from creating nice experiences on iOS for use cases where a business needs to share device between multiple users and OAuth is used as identity provider.
One of the “best” solutions I have come across is to open a logout page in system Safari (not an SFSafariViewController). Because ASWebAuthenticationSession shares cookies reliably with Safari, the expired/deleted cookie then also affects the app.
See this GitHub page for more details.
It depends on which cookie stores your login info;
If it is a session cookie, then it is not shared with Safari as per https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession
So, simply clear your local session, and the cookies will be cleared on the next app launch.
If not, and the cookie persists, then like Martin said above, you should open Safari (not SFSafariViewController) with your logout URL, then redirect back to your app.
Please let me know if you need more info. I have tested extensively with all 3 ways of authentication (ASWebAuthenticationSession, Safari, and SFSafariViewController).
For iOS 13.0 need to add SceneDelegate.swift for UISceneConfiguration
Also need to update appdelegate for UIScene implementation
Add UISceneSession Lifecycle
It is working fine this way SFAuthenticationSession issue resolved.
In one of our apps, we've already started using ASWebAuthenticationSession.
Our use case for this goes beyond just retrieving access and refresh tokens upon login. What I mean by this is, the same session cookie is used when opening the web app (whilst logged-in to the iOS app) in order to save the user from re-authenticating themselves again and again. Eventually, time comes when the user finally decides to log out of their account and may thereafter attempt to re-login again using a different account. Since the user's session cookie may still be alive by then, any re-login attempt only flashes the authentication screen momentarily, logging them in automatically back to their first account without giving them a chance to enter the credentials of the second account.
To really force the user to enter their credentials every time we present the authentication screen, we have to add to our Auth0 query params the prompt=login pair.
Here's what the URL would look like:
https://example.auth0.com/authorize?
client_id=abcd1234
&redirect_uri= https://example.com/callback
&scope=openid profile
&response_type=id_token
&prompt=login
You can find more info about this on this Auth0 doc: https://auth0.com/docs/authenticate/login/max-age-reauthentication

Is there a way to skip the "Your domain administrator has approved" page in Apps Marketplace Oauth2?

I have a Google Apps Marketplace (v2) app I am working on setting up Oauth2 for.
I've got everything working, but for some reason when I do a redirect to the authentication page, after, after you select which Google account to use (if like you're me and are testing, you have to pick one of several Google accounts you're currently signed into), I get sent to another page which seems utterly pointless:
This is bizarre and annoying, because I am logging in as the domain administrator!
Does anyone know a way to skip this screen, or what I might be doing to be cursed with this terrible user experience?
I just confirmed that having access_type=offline will always display this page, even with approval_prompt=auto. You will always get back a refresh token as well.
The only way to hide it is to remove access_type=offline on future login requests (ask only on signup).
I believe this shows up only if app requests refresh token for offline access. Also this should only appear first time you access the app after installation.
In order to skip this you need to update app to not request refresh tokens.

Google Oauth implementation on application login every time asking for permission to “Have offline access”, why?

My application is prompting each time for having offline access. Could you please help me how to configure this.
Lets say i have implemented for an application login. in that case asking for offline access each time.
It should ask only for the first time, Next time onwards it should just login.
Please let me know if i have to do some configuration for this.
Am using google-api-java-client Library. 1.17.0 version
Thanks in advance.
I don't know your login url, but I assume, that you are either still using the offline scope or approval_promt=force. Remove them both from your url, if you don't want the user getting prompted.
The problem: you don't know, if you already got a refresh token, so what you're going to want to do is, that you first log the user in, then check, if you need a refresh token and then redirect the user again to google with the right scope.

Has Google pushed an update to their OAuth2.0 flow that breaks multiple accounts?

Up until last week, when ever I was logged into multiple accounts in Google and I invoked the OAuth2.0 flow I would get to an ugly screen (looked like it had been hit repeatedly with the ugly stick) that was functional. It would display a list of radio buttons with all the accounts I am logged in as, you select the one and continue through the flow.
This week I now get a beautiful screen that is non-functional (does not list accounts and the signin button only adds an additional account to the list of accounts I am signed in as) I should point out that I am logged into 4 different Google accounts at the same time. The OAuth2.0 for my app appears to be working fine as if I start an in-cognito window in Chrome, or start a new session and only have one account logged in, my OAuth flow continues normally.
Is this just me or is everyone hit by it?
We (google) are rolling back the new page and within a few minutes it should return to the previous behavior.
Any chance you could let us know what kinds of accounts those 4 you were logged in to were? SAML? Google Apps? Plain gmail?
We're also experiencing this. Hope someone at Google takes note and gets this fixed soon!
EDIT: To clarify, I've only experienced the problem when logged into both a personal Google account AND a Google apps account. Haven't tested other situations at present.
FYI, we just rolled out the new UI, so you may begin to see the "beautiful screen" that is now functional. :-) Thanks for the bug report.

Handling Sign Up through api in Devise / Rails

I have created a simple API for a Rails application using token-based-authentication that supports User Log In and Log Out and a couple of other actions to update a User's status. I want this API to be used by devices running iOS. I have based my code on the example found here. In addition to allowing a device to login and update a User's status I would like new users to be able to Sign Up from the device. However looking at Devise's helper class I can't see any methods that support Sign Up, only Log In and Log Out.
Has anyone managed to implement Sign Up through an API? Are there any security issues with allowing this? How should I approach this?
Sign up from an iOS device is really just a (JSON?) POST to the User resource using a different format responder.
This data is passed in the clear from an iOS device, so make sure you use https on these routes if you're worried about security.

Resources