Persisting user on device with flutter and firebase auth - firebase-realtime-database

currently I made my first flutter app so there are things still uncertain for me. One of them is if there is a way to store the FireBaseUser in the device or construct it from information stored there, first to be able to get a new token to send http requests to my firebase backend adn second to maintain a login session after the app is closed until the user hits logout.
Thanks for any answer!

The Firebase plugin is smart enough to cache the user for you. You can just check the current user after the app has restarted.

Related

flutter - How to keep user signed-in with Google

I have used Google Sign In to authenticate users with Firebase Auth, and I successfully get back my Firebase User. I want to keep the user authenticated, when they come back to the app. How can I do the same?
Users already stay authenticated. After you restart the app, Firebase reads the credentials from disk, and refreshes the user's token. Since this requires a roundtrip to the server, it happens asynchronously. So be sure to await _auth.currentUser() to get notified of the user's status.
Whenever I'm wondering how to do such things, I look at the FlutterFire sample app. This specific line can be found here.
Yes you need to do the auth.currentUser() function in order to keep users authenticated and the best part is that this function will work even if the user is offline, which makes it very versatile.

Limiting an iOS app to installation on only one device

I have an iOS app written in Swift where I want to limit each account to one device only – what is a way that I could go about limiting this access? I'm using Firebase and have a login system but the login system is not linked to Firebase Auth.
After login the use generate the token and save them into dataBase. And send this token in header when you hit any other API. If new same use login on other device, update the token in data base .
Now you check this token is same or not if not then send repose code 401 and logout the user.
One option that also works, that I found through research, is to store the uid of a device in the database used in the app (or in NSUserDefaults) via UIDevice.current.identifierForVendor!.uuidString. Then, when a user logs in, compare the uuid with the device's uuid and take the appropriate action.
This is not foolproof – if the user uninstalls the app and re-installs it, they will be assigned a different uuid. But in general, this is the best approach.

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

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.

iOS Facebook SDK - Manually Expire a Session - Kiosk App

I'm struggling with the darn Facebook SDK.
I'm writing a 'kiosk app' i.e. an App that will have multiple users use it throughout the course of a day - each user can optionally send info unto their Facebook accounts ( and I need to use the Graph API so I can't use ShareKit ), and then I need to get them to manually logout or it will do so automatically after a short timeout.
In either case it MUST forget their credentials and session data, so that when the next user ( even just moments after ) presses the Facebook button it won't try and use the previous users credentials and log automatically into the wrong account.
I'm even manually calling '[facebook logout:self];' and that NEVER does anything.
Please, can anyone help?
Call auth.expireSession on the REST API.
https://developers.facebook.com/docs/reference/rest/auth.expireSession/
I recently had to this for a kiosk app at f8. Nothing exist from the graph API yet to do this.

Resources