How to verify user is authenticated entire app Xamarin Form - android

I'm new with Xamarin form, my question is how can I check user is logged in for entire app, example every time when users go to a new page, it checks for authent. I tried successfully for every page check for auth but is there any another ways to do it? I did some research on internet and some said that i have to auth on the App.cs on OnStart() but the event is not raise when i go to the next page, it starts only when user open the app.
Here is my code, I'm using Google auth.
On the logged in page (HomePage):
public HomePage(NetworkAuthData networkAuthData)
{
if (string.IsNullOrEmpty(networkAuthData.Id))
{
//Always require user authentication
//Application.Current.MainPage.Navigation.PopAsync();
Application.Current.MainPage = new NavigationPage(new SocialLoginPage(oAuth2Service));
}
else
{
BindingContext = networkAuthData;
InitializeComponent();
}
}
It works but when i move these code to app.cs on OnStart() it just run once when opened the app.

Related

Xamarin Forms: Android CustomTabs close when app is backgrounded

TL;DR: CustomTabs close when app is backgrounded, but we need it to stay active. How can we achieve this?
We have an app which uses CustomTabs to login the user. We have added two-factor authentication, but this introduces a problem. When you tap the login button the custom tabs intent is launched as this:
var tcs = new TaskCompletionSource<BrowserResult>();
try
{
var activity = (Activity)Forms.Context;
var builder = new CustomTabsIntent.Builder().EnableUrlBarHiding();
var customTabsIntent = builder.Build();
customTabsIntent.Intent.AddFlags(ActivityFlags.NoHistory);
Action<string> callback = null;
callback = url =>
{
MainActivity.Callbacks -= callback;
tcs.SetResult(new BrowserResult
{
ResultType = BrowserResultType.Success,
Response = url
});
};
MainActivity.Callbacks += callback;
customTabsIntent.LaunchUrl(activity, Android.Net.Uri.Parse(options.StartUrl));
}
catch (Exception ex)
{
throw new Exception($"error: {ex.Message}");
}
return tcs.Task;
This works as expected and you can login, of course now the code for two-factor authentication code is asked, which in most cases means you have to background the app, open your authenticator (authy, Google authenticator etc.) and then come back to the app with the code. The problem is that when we re-open the app the CustomTabs and it's session is completely gone. This means you have to click it again, login again and the same happens all over. I have searched for a solution for days now. Can anyone help us finding a way to keep the CustomTabs and it's session open, so you can just fill in your authenticator code and login happily ever after?
Okay it seems to be that the following code that someone added was the one causing this:
customTabsIntent.Intent.AddFlags(ActivityFlags.NoHistory);
I removed it and it seems to work now. I see some other issues going on, but I don't think this has to do with this issue. If it does I will let you know here.

AppAuth Relogin

After some back and forth I finally got this to work but I had to use version 0.2.0 because I followed the google guide presented in the Readme.
Anyway, Im struggling with handling what will happen when the oAuth token times out. Then it needs to open the browser again to log in or is there a background process available for this as it automatically redirects back to the app because the server remembers the user so there is no need for a new username/password input?
Im getting a refresh token like this :
if(mAuthService == null){
mAuthService = new AuthorizationService(context);
}
mAuthState.performActionWithFreshTokens(mAuthService, new AuthState.AuthStateAction() {
#Override public void execute(
String accessToken,
String idToken,
AuthorizationException ex) {
if (ex != null) {
return;
}
// Getting the access token...
}
});
Thats working fine but after the user is idle for some time it wont work. How to handle this properly?
Solution for my problem was this:
I changed to using offline_access for the token in the scope. Depending on the site/service you're login into if they accept it or not. For me it was accepted and will keep the user logged in for a long time and removes the need to re-login.

Flutter: How to handle screens that require authentication?

I'm building a Flutter app where some screens can be shown to anonymous users, and other screens require a user to be logged in.
For the authenticated screens, they should automatically navigate to (push) a login screen if the user is not logged in. A user session can expire at any time and if the user is viewing one of these authenticated screens then the login screen should be shown immediately at that time.
In Flutter, how can I achieve this notion of authenticated screens that automatically navigate to/from a login screen when the user is not authenticated?
Currently, there's nothing that flutter do with Authentification and Authentified routes.
The problem is that dart:mirror is disabled, which prevents from doing a more automated solution.
You could try to :
Put Anonymous routes in MaterialApp's routes property
Put Authentified routes in MaterialApp's onGenerateRoute property
And make sure inside onGenerateRoute that the user is logged. If he is, build that route. If not, build the Login route with the original destination passed as parameter (to later redirect to that page)
A code generator may be a good solution too ; although more complex.
There is a really good package auto_route for flutter.
It gives you a lot of power to implement Route Guards for Authenticated routes.
I'm encouring you to use the latest version of the library (on this time I'm writting the ansewer https://pub.dev/packages/auto_route/versions/1.0.0-beta.8 is the latest one)
The documentation is missleading but https://github.com/Milad-Akarie is actively working on that library and respond on any question under Issues tab on GitHub.
There is an example solution: https://github.com/Milad-Akarie/auto_route_library/tree/master/example
AppRouter.dart
...
AutoRoute(path: RoomPage.path, guards: [AuthGuard],page: RoomPage),
...
AuthGuard.dart
class AuthGuard extends AutoRouteGuard {
#override
Future<bool> canNavigate(
List<PageRouteInfo> pendingRoutes, StackRouter router) async {
bool isAuthenticated = await checkUserAccess();
if (!isAuthenticated) {
router.root.push(LoginRoute(onLoginResult: (success) {
if (success) {
router.replaceAll(pendingRoutes);
}
}));
return false;
}
return true;
}
}

OneDrive - How to retrieve authorization access data?

I develop an android application which use OneDrive API. When I connect to OneDrive, it asks me to authenticate and show an authorization page (with permission to access to my data on the cloud).
My problem is : Every time I upload data on the cloud, the application shows me the authorization page. I would like this page to not appear every time. How can we find that it already recorded please ?
Thank a lot !
When using the LiveSDK for Andriod, there is an assumption that the user is authenticated at all times when using the application, in order to preserve this flow, we require that you call LiveAuthClient.initialize(...) to renew the user credentials (without any user input) or call LiveAuthClient.login(...) in order to perform an interactive login (User entering username/password).
In the LiveSDK sample apps we see this implemented with a startup activity called SignInActivity.java Here are the relevant excerpts to perform the silent credentials renewal:
protected void onStart() {
super.onStart();
mAuthClient.initialize(Arrays.asList(Config.SCOPES), new LiveAuthListener() {
#Override
public void onAuthError(LiveAuthException exception, Object userState) {
mInitializeDialog.dismiss();
showSignIn();
showToast(exception.getMessage());
}
#Override
public void onAuthComplete(LiveStatus status, LiveConnectSession session, Object userState) {
mInitializeDialog.dismiss();
if (status == LiveStatus.CONNECTED) {
launchMainActivity(session);
} else {
showSignIn();
}
}
});
}
The launchMainActivity() function moves the user into the primary application code, this would be where your application starts in earnest. To see the full details of this sign in activity take a look at the sample app SignInActivity.java in Github

Facebook Android Unity can't post screenshot

I made a unity project and included facebook in it. Everything worked fine until I used OBB spliter.
Actually, I just wanted to share a screenshot of the game so I did this:
private void CallFBLogin()
{
print ("test");
FB.Login("email,publish_actions", LoginCallback);
StartCoroutine (TakeScreenshot ());
print ("test2");
}
When I push a button, this function is called but the problem is that the process finishes before I'm logged with Facebook. When I'm logged in, I'm already out of this function. What's the best way to log, wait to be logged and then launch the coroutine?
I haven't used the Facebook api yet so I can't give you exact code but based on what I see here you need to launch your coroutine from inside the LoginCallback function.
This way it will automatically execute after the user is logged in.
As TheValar stated, you need to do the following..
private void CallFBLogin()
{
print ("test");
FB.Login("email,publish_actions", MyLoginCallback);
print ("test2");
}
void MyLoginCallback(FBResult result)
{
// Do whatever you need, or nothing. You can check if you are logged in correctly
StartCoroutine (TakeScreenshot ());
}
This will guarantee that the take screenshot gets called after you are logged in Facebook

Categories

Resources