I am using firebase authentication and facebook authentication to facilitate users auth.
But when I click the button for face book auth it stops loading and nothing happens.
and in the release mode the link doesn't open.
I have tried all youtube videos to make facebook auth work.
This is my source code:
Future<UserCredential> signInWithFacebook() async {
// Trigger the sign-in flow
final LoginResult loginResult = await FacebookAuth.instance.login();
// Create a credential from the access token
final OAuthCredential facebookAuthCredential =
FacebookAuthProvider.credential(loginResult.accessToken!.token);
// Once signed in, return the UserCredential
return _auth.signInWithCredential(facebookAuthCredential);
}
Facebook have already updated their api for signin options.
try reading this links it might help
ff:
[https://pub.dev/packages/flutter_facebook_auth]
[https://medium.com/flutter-community/flutter-facebook-login-77fcd187242]
![and also for the fb api i have use a webview to fetch it and send the request to the post]
Related
After some hours of research in vain I stay confused how to do the following:
I have a flutter app which authenticates via OAuth2 to Google (google_sign_in) and Facebook. For Facebook this is the code:
final LoginResult loginResult = await FacebookAuth.instance.login();
final userData = await FacebookAuth.instance.getUserData();
print(userData);
Which prints: {email: john.doe#email.com, id: 123456, name: John Doe}
I already have a webpage with OAuth2 authentication built in Flask/Python. Now I want my users to be able to both use Web and App and share the preferences/data/etc.
How would I achieve that? In my Flask webapp I'm just creating a user in my database if it doesn't exist and then use some authentication headers in subsequent calls. So I thought with the app I could…
send what I got from OAuth to the api and create the user if it does not yet exist
return some sort of token (with a TTL?)
verify the tokens being sent by the app
But this is a lot of custom boilerplate code, I'm sure that this is existing somewhere/somehow. Additionally: How can I be sure someone is not "tampering" my app via decompile, proxying or just plainly calls my api and claiming to be someone else?
My security requirements are medium: The app will eventually have messaging but won't be used for things like money transfer.
I'm considering these options:
PKCE but this looks like the OAuth2 flow would go through my flask api and that sounds too complex (I had a hard time already getting OAuth2 to work in flutter alone)
Resource Owner Password Credentials Grant which sounds like I can somehow pass the results of OAuth2 to my api, get back a token and use this in subsequent requests. However this seems like an outdated protocol (top google results are articles from oracle)
firebase implementation: they use the same flow: first OAuth2 authentication and then passing the credentials into their servers api. On the first time they pass the credentials a user is created and stored in the database, etc. But my reverse engineering skills are not good enough to figure out how it's done.
using a webview and use the oauth2 of my flask website. I'm shying back from this because it would be not a nice mobile experience plus I would not know how to read/store these credentials
After a lot of reading I found a good article on auth0 , in essence there are two options:
Resource Owner Password Flow - use this if you totally trust your app, e.g. when you deploy it to a closed group of users for which you have device management in place. This situation doesn't apply for me and also Auth0 doesn't recommend it. Still, it would have been relatively easy to implement.
PKCE (Proof Key for Code Exchange) - use this when the client cannot be trusted (IMO 99.9% of mobile apps). But this needs some fancy protocol between the mobile app and the server and alone by looking at the flowchart diagram I got headaches
As PKCE looks too complicated to implement myself I decided to go with Firebase, which helps small projects such as mine where you don't want to go through the pain to code the whole PKCE flow yourself.
What I did was:
adding firebase authentication to my flask app, using flask-firebase - this was worth it since it decreased the lines of python code by 40%. Because the module lacks good documentation I wrote this blog post which explains how to use it
adding firebase authentication to flutter. This is very well documented e.g. here
The whole flow then works like this:
flutter triggers the oauth flow for e.g. google
flutter gets back the auth details, including email address, name, etc. (depends on oauth provider)
the auth details are sent to firebase which creates the user if it doesn't exist yet, enriches it with a user id and packs it into an encrypted token
the token is sent to flask, which verifies the token against firebase
flask logs the user in (via flask_login) and returns a session cookie
the session cookie is stored in flutter (using requests) and used for subsequent api calls
to preserve the user logged in even after app close, the session is stored in apps preferences (using shared_preferences)
In essence, this is the code needed (google social login example):
Future<String?> signInWithGoogle() async {
final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();
final GoogleSignInAuthentication? googleAuth =
await googleUser?.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth?.accessToken,
idToken: googleAuth?.idToken,
);
UserCredential userCredentials =
await FirebaseAuth.instance.signInWithCredential(credential);
return userCredentials.user?.getIdToken();
}
…
var cookies = await Requests.getStoredCookies('example.com');
SharedPreferences? prefs;
if (!cookies.keys.contains('session')) {
prefs = await SharedPreferences.getInstance();
if (prefs.containsKey('session')) {
print('cookie not set, load session from prefs');
await Requests.addCookie(
'example.com', 'session', prefs.getString('session')!);
}
}
cookies = await Requests.getStoredCookies('example.com');
if (!cookies.keys.contains('session')) {
print('cookie not set, prefs contain no session, signing in');
String? idToken = await signInWithGoogle();
if (idToken != null) {
await Requests.post('https://example.com/auth/sign-in',
body: idToken,
headers: {'Content-Type': 'application/jwt'},
bodyEncoding: RequestBodyEncoding.PlainText);
var cookies = await Requests.getStoredCookies('example.com');
prefs?.setString('session', cookies['session']!.value);
}
}
var r = await Requests.get('https://example.com/api/something_which_requires_login');
The important part happens with Requests.post: this posts the idToken of firebase to flask, which in turn then verifies the token, calls login_user and returns response with the session cookie header. This cookie is stored by requests and is added to subsequent http requests.
Because this is some mouthful I created this blogpost which explains this in more detail.
I'm using Plugin.FacebookClient for FB authentication with AuthO SSO at backend using FB SessionToken. I can able to login, retrieve the SessionInfoToken but when try to LogOut using the FacebookClient.Current.Logout() method it doesn't logout the user from the app.
When we try to logIn back through FB it directly moving to the Continue page instead of asking username and password.
I tried clear cookies, clearing secureStorage and App preference data but no luck yet.
_auth0Client = new Auth0Client(new Auth0ClientOptions
{
Domain = "YOUR_DOMAIN",
ClientId = "YOUR_CLIENTID"
});
then
await _auth0Client.LogoutAsync();
SecureStorage.Remove("accessToken");
CookieManager cookieManager = CookieManager.Instance;
cookieManager.RemoveAllCookie();
cookieManager.RemoveSessionCookie();
cookieManager.Flush();
I'm trying to create a Login through Facebook button in my Flutter project using Firebase. I added all the things Facebook asked and I have also set my app in Live mode. But when I try to Login, it says
App not setup: This app is still in development mode.
Here's the code I've used in my flutter project:
Future<UserCredential> _signInWithFacebook() async {
final AccessToken result = await FacebookAuth.instance.login();
final FacebookAuthCredential facebookAuthCredential =
FacebookAuthProvider.credential(result.token);
return await FirebaseAuth.instance.signInWithCredential(facebookAuthCredential);
}
How do I solve this?
I am using the plugin flutter_facebook_auth: ^3.3.2-no-nullsafety on my Flutter app. Users can log in using Facebook to get Firebase Authentication:
LoginResult facebookLoginResult = await FacebookAuth.instance.login(
permissions: ['user_friends'],
loginBehavior: LoginBehavior.WEB_VIEW_ONLY);
if (faceBookLoginResult.status == LoginStatus.success) {
AccessToken _accessToken = facebookLoginResult.accessToken;
final userData = await FacebookAuth.instance.getUserData();
final FacebookAuthCredential facebookAuthCredential =
FacebookAuthProvider.getCredential(accessToken: _accessToken.token);
name = userData['name'];
await FirebaseAuth.instance
.signInWithCredential(facebookAuthCredential);
}
}
The code works as expected. But after a Facebook user is logged on to a device, I cannot sign in as a different user. For example, if I restart and go to the login dialog, and then enter login name and password for a different user, I get the dialog box: "You previously logged in to (this app) with Facebook. Would you like to continue?" The only options are "Continue", which signs in the previous user, or "cancel", which cancels the sign in.
I have tried a number of other ways to remove the Facebook user from the device :
Clearing the app cache on the device
Clearing the browser cache on the device
Deleting the Facebook user in the "Authentication" panel of the Firebase Console
Deleting the instance of the Facebook user altogether (it was a Facebook test user)
None of this worked.
I would really appreciate some help as it is impossible to debug the login flow if I can't sign in as a new user to test.
For a Flutter mobile app I am trying to use a Microsoft OAuthProvider to get a Firebase credential with which to sign the user into Firebase with their Azure AD account.
The closest I got was using a third party Active Directory auth package to log the user in and get an access token. However the sign-in to Firebase fails with an error message that suggests the idToken is invalid.
final AadOAuth oauth = new AadOAuth(config);
await oauth.login();
// accessToken looks legit
String accessToken = await oauth.getAccessToken();
String idToken = await oauth.getIdToken();
OAuthProvider provider = OAuthProvider('microsoft.com');
// Also tried the constructor without the idToken
OAuthCredential credential = provider.credential(accessToken: accessToken, idToken: idToken);
// app fails here:
await FirebaseAuth.instance.signInWithCredential(credential);
// this works fine, but only on web platform:
await FirebaseAuth.instance.signInWithPopup(provider);
Because it is a platform specific error (iOS in this case), the exception details are not surfaced. All I get is:
PlatformException(internal-error, ) nativeErrorCode: 17999
Here is my app settings in the Azure portal:
Full manifest here
Has anyone been successful in using Microsoft Auth to sign a user in to Firebase in a Flutter mobile app?
You can use Firebase Auth OAuth package for it.
And sign in to the firebase using the Microsoft Auth provider.
User user = await FirebaseAuthOAuth().openSignInFlow(
"microsoft.com", ["email openid"], {'tenant': 'your-tenent-id'});
This integrates nicely with firebase so, firebase authStateChange also works with this method.
You have just to not receiving idToken, just verify that you have add the id_token for the response_type and also openid scope like
provider.addScope('openid');
Also check weather you have allowed implicit flow with id token in the Azure portal app settings (you sould check ID tokens on the Authentication tab under Implicit grant section).
Ok than have you added Microsoft as a authentication provider in the firebase authentication configuration Sign-in method page? And also have you tried to authenticate with Auth, after getCredentials method as stated in the documentation?
provider.getCredentialWith(nil) { credential, error in
if error != nil {
// Handle error.
}
if credential != nil {
Auth().signIn(with: credential) { authResult, error in
if error != nil {
// Handle error.
}
// User is signed in.
// IdP data available in authResult.additionalUserInfo.profile.
// OAuth access token can also be retrieved:
// authResult.credential.accessToken
// OAuth ID token can also be retrieved:
// authResult.credential.idToken
}
}
}
firebase authentication package has a method called signInWithPopup so you don't need firebase_auth_oauth anymore. here my code:
Future<UserCredential?> loginWithMicrosoft() async {
OAuthProvider provider = OAuthProvider('microsoft.com');
provider.setCustomParameters({
"tenant": "your-tenant-id",
});
provider.addScope('user.read');
provider.addScope('profile');
try {
final userCredential = await FirebaseAuth.instance.signInWithPopup(provider);
return userCredential;
} on FirebaseAuthException catch(err) {
debugPrint(err.message);
// Handle FirebaseAuthExceptions
// ex: firebase_auth/account-exists-with-different-credential
}
}
Remeber add the redirect URI and enable de scopes in Azure Portal.