Firebase authentication with custom backend - ios

I plan to use Firebase for authentication for my iOS app. But I want to use custom backend for rest of the REST APIs. How can I add authorization for users authenticated with Firebase in my custom backend ? Can we use both custom backend and firebase authentication? How do I maintain the session using both Firebase and custom backend?

You can verify the token on your backend server with the firebase Admin SDK.
So on the app you get a firebase access token and send this to your server.
On IOS you do:
FIRUser *currentUser = [FIRAuth auth].currentUser;
[currentUser getIDTokenForcingRefresh:YES
completion:^(NSString *_Nullable idToken,
NSError *_Nullable error) {
if (error) {
// Handle error
return;
}
// Send token to your backend via HTTPS
// ...
}];
More Info here:
https://firebase.google.com/docs/auth/admin/verify-id-tokens#retrieve_id_tokens_on_clients
On the server you do:
admin.auth().verifyIdToken(idToken)
.then(function(decodedToken) {
var uid = decodedToken.uid;
// ...
}).catch(function(error) {
// Handle error
});
As you can see you even get the "uid" of the user.
More Infos here:
https://firebase.google.com/docs/auth/admin/verify-id-tokens

Related

Swift - Firebase Auth with Microsoft Graph (Redirect URL Problem)

I'm having a problem integrating Firebase with Microsoft Auth in my iOS App.
The login page has been launched and I can sign in by Office365 account but login auth can not be finished because of the below Error :
"AADSTS50011: The reply url specified in the request does not match the reply urls configured for the application:[app-id]"
I did check the setting in Firebase and below are the settings I add in the app of Azure Active Directory :
Web redirect URL : "*.firebaseapp.com/__/auth/handler"
Supported account types : "Accounts in any organizational directory (Any Azure AD directory Multitenant)"
Here are the swift code I implement :
provider = OAuthProvider(providerID: "microsoft.com")
provider?.customParameters = ["prompt": "consent",
"login_hint": "Login Hint"]
provider?.scopes = ["mail.read", "calendars.read"]
provider?.getCredentialWith(_: nil){ (credential, error) in
if let credential = credential {
Auth.auth().signIn(with: credential) { (authResult, error) in
if let error = error {
print(error.localizedDescription)
}
}
}
}
Does anyone know how to solve the problem or have the same problem?
When registering apps with these providers, be sure to register the
*.firebaseapp.com domain for your project as the redirect domain for your app.
Have you replaced * with your projectName? You can find your Authorized Domain under Authorized Domains in firebase console. The redirect uri should be something like
https://yourFirebaseApp.firebaseapp.com/__/auth/handler

iOS ADAL-Make silent call using refresh token

I am using iOS ADAL library version 2.2.6 and receiving refresh token upon successful login. Now I want to make a silent call by using this refresh token. I tried with following method but it fails to return the access token.
ADAuthenticationContext *authContext;
[authContext acquireTokenSilentWithResource:resourceId
clientId:clientId
redirectUri:redirectUri
userId:strUserID //loggedIn userID
completionBlock:^(ADAuthenticationResult *result){
// It alway throws an error //Please call the non-silent acquireTokenWithResource methods.
if(result.error){
ADAuthenticationError *error = nil;
authContext = [ADAuthenticationContext authenticationContextWithAuthority:inputData.authority error:&error];
[authContext acquireTokenWithResource:inputData.ResourceID
clientId:inputData.ClientId // Comes from App Portal
redirectUri:inputData.RedirectUri // Comes from App Portal
completionBlock:^(ADAuthenticationResult *result)
{
if (AD_SUCCEEDED != result.status){
// Show alert with error description
}
else{
//Handle Success token
}
}];
}else{
//Handle Success token
}
}];
But it always throws an error saying "The user credentials are needed to obtain access token. Please call the non-silent acquireTokenWithResource methods."
Is there any way to make a silent call using refresh token? please help me on it. Thanks in advance.
When you use Microsoft's authentication libraries, you should always first check to see if there is a user in the cache that can be used for your resource before prompting the user to sign in. This allows us to check if the user had previously signed in to your app or if there are other apps that share state with your app that may have already asked the user to sign in elsewhere.
If the user is found, we will try to acquire a token without interrupting the user at all. Sometimes a user will have changed their password or done some other action that will require them to sign in again even if they have signed in to your app previously. This is what you are seeing. The library is telling you that for the user you are trying to acquire a token for, they need to sign in again to make something right.
In order to handle all these cases elegantly, we recommend that you use the pseudocode pattern of:
acquireTokenSilent()
(if error InteractiveAuthenticationRequired) {
acquireTokenInteractively() }
The pattern first checks if a user you specify is available in the token cache. If it is, we then call the Azure Active Directory service to see if the Refresh token for that user is valid. If both of these are true, then the user is signed in silently. If the user isn't found or the server rejects the Refresh Token, then an error is sent from the library that indicates the user needs to sign in interactively.
In the above, you are doing this first part, but you aren't handling the case where the user needs to sign in if there is a problem.
The best way is to catch the error with a ADErrorCode of AD_ERROR_USER_INPUT_NEEDED
Here is a code sample on how to do this pattern.
// Here we try to get a token from the stored user information we would have from a successful authentication
[authContext acquireTokenSilentWithResource:data.resourceId
clientId:data.clientId
redirectUri:redirectUri
userId:data.userItem.userInformation.userId
completionBlock:^(ADAuthenticationResult *result) {
if (!result.error)
{
completionBlock(result.tokenCacheStoreItem.userInformation, nil);
} else {
if ([result.error.domain isEqual:ADAuthenticationErrorDomain] && result.error.code == AD_ERROR_USER_INPUT_NEEDED) {
// Here we know that input is required because we couldn't get a token from the cache
[authContext acquireTokenWithResource:data.resourceId
clientId:data.clientId
redirectUri:redirectUri
userId:data.userItem.userInformation.userId
completionBlock:^(ADAuthenticationResult *result) {
if (result.status != AD_SUCCEEDED)
{
completionBlock(nil, result.error);
}
else
{
data.userItem = result.tokenCacheStoreItem;
completionBlock(result.tokenCacheStoreItem.userInformation, nil);
}
}];
} else {
completionBlock(nil, result.error);
}
}
}];
Keep in mind this code is very verbose. You will most likely want to have acquireTokenWithResource: a separate method that you could call with [self acquireTokenWithResource]

Firebase auth custom token iOS

I am trying to add to my app VK authorization with Firebase SDK.
When user authorization finished, I try to pass token to Firebase.
func vkSdkAccessAuthorizationFinishedWithResult(result: VKAuthorizationResult!){
let tokenString = result.token.description
FIRAuth.auth()?.signInWithCustomToken(tokenString) { (user, error) in
// ...
}
}
Error: [1] (null) "NSLocalizedDescription" : "The custom token format is incorrect. Please check the documentation."
Can I use Firebase with custom auth without running server?
From Firebase Doc. Create custom tokens using the Firebase SDK,
I would say that you need to use createCustomToken() method for this.. you can not use your VK servers token to signIn with firebase ... you need to generate token for firebase with createCustomToken() method.
var uid = "some-uid";
var customToken = firebase.auth().createCustomToken(uid);
May this work for you

Office 365 AD Authentication with ADAL: missing parameter 'client_secret or client_assertion'

I'm trying to authenticate in Microsoft Office 365 Azure AD. For the purpose I'm using Microsoft ADAL library for Objective-C version 1.0. Here is a sample code:
ADAuthenticationError *error;
ADAuthenticationContext *authContext = [ADAuthenticationContext authenticationContextWithAuthority:#"https://login.microsoftonline.com/...." error:&error];
[authContext acquireTokenWithResource:#"https://login.microsoftonline.com/..."
clientId: #"AAAAAA-AAAA-AAAAA-AAAA-AAAAA";
redirectUri:[NSURL URLWithString:#"https://localhost:11111"];
userId:nil
extraQueryParameters:#"client_secret=AAAAABBBBBCCCCC"
completionBlock:^(ADAuthenticationResult *result) {
if (AD_SUCCEEDED != result.status){
NSLog(#"%#", result.error.errorDetails);
} else {
NSLog(#"%#", result.accessToken);
}
}];
I get
Error -- AADSTS90014: The request body must contain the following parameter: 'client_secret or client_assertion'.
ADAL for ObjC only works for public clients, which do not use secrets - and in any case, adding it via extraqueryparameters wouldn't help. How did you register your application in Azure AD? I suspect you might have registered it as a web app (which is a confidential client, requiring client creds when requesting tokens) while it needs to be registered as a native client.

Is it possible to cache the auth token to speed up login in Firebase with iOS?

I'm authenticating to Firebase with FirebaseSimpleLogin and Email/Password authentication in iOS. It seems that making the [authClient loginWithEmail:username andPassword:password withCompletionBlock:^(NSError *error, FAUser *user) { ... }]; takes roughly 5-8 seconds to complete.
Is there a way to speed up the login, like caching the authToken from FAUser, and using starting to use that directly in the first Firebase call?
Update:
It seems that storing the authToken after a successful login to NSUserDefaults:
[[NSUserDefaults standardUserDefaults] setValue:user.authToken forKey:USERDEFAULTS_LOGIN_TOKEN];
[[NSUserDefaults standardUserDefaults] synchronize];
... and then doing an authWithCredential: call with the stored authToken on next login attempt:
NSString *authToken = [[NSUserDefaults standardUserDefaults] stringForKey:USERDEFAULTS_LOGIN_TOKEN];
if (authToken) {
NSLog(#"Firebase logging in with token...");
[[Mesh root] authWithCredential:authToken withCompletionBlock:^(NSError *error, id data) { ...
... isn't any faster. Is there another way to speed up the login?
With the release of the Firebase iOS / OS-X Client v1.2.0, Firebase caches the local client authentication state and greatly optimizes the speed of re-authentication. Previous client versions required multiple server roundtrips before the client would enter an "authenticated" state, but this is now immediate if a valid, persisted session has been located on-disk.
Also note that Firebase Simple Login has been deprecated and replaced with a reimplementation of Firebase authentication that is enabled in the core Firebase client libraries. Check out https://www.firebase.com/docs/ios/guide/user-auth.html for the guides on how to get started with it on iOS.

Resources