i am working with the HelloFacebookSample from face book's sdk.
i have a few issues, but am trying to get through them.
The one i have right now is that after I login, then logout, then login again, i am automatically logged in without being asked for credentials. Is there any way to change this behavior?
And secondly (for now), is there any way i can bring up the FB login dialog within my app instead of it going to Safari? i don't want my users to have access to safari at all, so i need to keep control.
The original FB sdk (about 2 years old) handled the login directly from within the app, so I am thinking i am just missing something here?
Thanks,
Jerry
If you want full control over the login process then you can't use the SDK, you need to add and manage a web view yourself. Facebook tries to bother the user to reconfirm as little as possible, so it will provide a login with the least path of resistance (and user taps / interaction).
Depending on how the user is logged into Facebook you won't be able to force them to re-enter login details unless you implement the web view approach. If you're using the SDK then you would need to call closeAndClearTokenInformation on the active session and also delete any Facebook related cookies from the app (and that's probably as close as you can get).
Related
I want to open, from an iOS app, a web page that requires authentication in order to get to that page.
I googled a little bit and I believe I need to use WebKit and Javascript injection, but I am not sure and I have never done something like this, so every bit of information is welcomed or pointing me in the right direction.
I will give an example that I hope will make things more clear(I don't actually want to open facebook, it's just part of the example):
Is it possible to do the following scenario? And if yes, how?
Open a web page from an iOS app, for example: "https://www.facebook.com/profile" without having to go through the login page? I do have the user credentials(username and password), as the user is already logged in with those credentials in the iOS app, but the requirement is to not go through the login page, but to go straight to the profile page.
In general the answer is: no. Even if the user is already logged in and has a valid authentication token that token may only be valid from within your app and not from within the browser. And the login form may be protected by something like a captche preventing you from automatically logging someone in.
There certainly are situation where it is possible: For example if the tokens are not scoped to your app you can try passing them along. Or there is an actual API that you can call with the token that logs the user into the website on the website, etc. But those depend on the specific target website or wether you can control that target website and can add this functionality.
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
I am developing iOS App which use Facebook iOS SDK 4.
When user has already done Facebook login, by doing Facebook login the dialog which shows "user has already approved your app" had be displayed.
So, do not show the dialog. I want to know whether the user has already done Facebook login.
Anyone know the good way? I think accessToken is returned if user once had done Facebook login.
FBSDKAccessToken manage current logged user's accessToken.
According to official Facebook Login guide
"FBSDKAccessToken Represents the access token provided by a successful login. Most important, it provides a global +currentAccessToken to represent the currently logged in user."
The currentAccessToken is a convenient representation of the token of the current user and is used by other SDK components (like FBSDKLoginManager).
According to above you can check either user has valid accessToken or not and based on this you can track call login method otherwise just skip to next flow.
In Facebook the access tokens are per user so you can pass them around apps and they will work. In your case if you can ship an access token from another app you will be able to skip the next logging in and use the API normally.
However I think this this thread will help you.
Things are a little bit different with iOS cause I have done a facebook login on Android and got no such issues.
I am using omniauth-facebook and omniauth-twitter gems to enable log in via Facebook, Twitter.
Everything works fine, I am able to authenticate user using OAuth. The BIG problem here is that when user is signed out from my application, it doesn't log out
from the social site that they authenticated from, which is dangerous.
I would like to add a functionality that will destroy the session in both places i.e, my application and the corresponding social site.
How do I do that?
Is it possible using the omniauth gems that I am currently using? Or is there an alternative gem/API available to achieve this?
It seems to me that the problem is we don't know the user's intent. If the user logs out from your app and they don't have other tabs open with Facebook and then they walk away from the computer thinking they're all done but leave the browser open, then yes, that would be bad. On the other hand, if they have another tab which is on Facebook, if they log out of your app and then switch to the other tab expecting to carry on using Facebook, they'll be annoyed. You could argue that annoying people is better than leaving them logged in to Facebook unwittingly - I'd generally agree!
I don't know of a nice/official way to do this if you're handling the login flow server-side. Some suggest building a normal Facebook url - see https://stackoverflow.com/a/8765863 - and I guess you could redirect to that and make it redirect back if that approach still works (it's an old answer), but it feels brittle as the user implies.
If you're using the javascript api, there's the FB.logout function:
https://developers.facebook.com/docs/reference/javascript/FB.logout/
and/or the auto-display of a logout button instead of the login button using the auto_logout_link parameter:
https://developers.facebook.com/docs/plugins/login-button/
One option which covers both user intent scenarios is to have your normal logout button which obviously kills your app's session and when they click it, redirect to a page which has a "Logout from Facebook?" button - perhaps using the javascript login button with the auto_logout_link parameter. Then they can logout from Facebook if they're done with the computer, or choose not to click it if they have Facebook open in another tab and want to continue using it.
As I'm sure you know, omniauth-facebook supports both server-side and client-side login flows.
I'm not sure if an equivalent is possible with omniauth-twitter - I don't have experience with it.
I have used latest FB SKD in my iOS app so users can use facebook account to login. Application open the FB app and comes back to my app perfectly fine. However, in some place in the app, i have to show/pull some people facebook page (safari based using WebView), but even user already used the Facebook account to login into my native ios app, but the page still ask user to login again and when they click login, it shows them the annoying FB username/pass page.
Is there anyway, that the FB safari based page can authenticate the user since it's already logged into my app using FB integration? do i have to include query or something. Please give me details how to solve this problem since i'm new in this..
thanks again for your help...
pic: https://www.dropbox.com/s/rjlptu7ufpcq3vl/fb.png
When the user switches to Facebook app to authenticate, it doesn't create a cookie for your UIWebView which is why it's asking to login again. Have the user authenticate inside the UIWebView without switching to the Facebook app.
What you're talking about also sounds like a similar thing that happens with Facebook dialogs not knowing about the current Facebook session.
If you authenticate your user via Facebook, try saying the Facebook object itself as an instance variable somewhere in memory so you can access it again (a property on a singleton controller, perhaps?).
Spawning dialogs from an authenticated Facebook object appears to let them use the dialog without reauthenticating iff you have a [FBSession activeSession]. So you'd also have to maintain an active FB session. But I'm not sure if this kind of solution will work since you didn't show specific code for how you're doing your web-based FB fetches.
This question might also prove helpful:
Implement Login with Facebook in iOS 5 and 6