Getting a unique id after biometrics authentication in flutter - authentication

In flutter, the local_auth plugin provides a way to authenticate users using biometrics. But it only returns a Future<bool> response:
var localAuth = LocalAuthentication();
bool didAuthenticate =
await localAuth.authenticateWithBiometrics(
localizedReason: 'Please authenticate to show account balance');
I wonder if there is any way to retrieve some unique ID to know which user has logged into the system.
EDIT: In android, after authentication it returns a BiometricPrompt.AuthenticationResult object which contain a MAC id. I am looking for something like that in flutter.

I don't know how you are implementing the unique with biometric. But here is the plugin which is a unique id provider based on a device.
https://pub.dartlang.org/packages/unique_id
Have a look
Very lightweight plugin, single line code for getting the unique id

Related

Strapi, use Auth0 to access user data in Strapi

I have a React Native app that uses Strapi for its main API.
Some of the API endpoints require authentication so I've used the Auth0 provider and that's all working fine.
A user is now able to log in and I'm securely storing their access_tokens.
So far, Auth0 only gives me an access_token, a refresh_token, an id_token (jwt containing name and email etc) and expiry times for the tokens.
But I'm wondering if it's possible to be able to store a users preferences like whether they prefer dark or light theme etc and extra info such as a user_id in Strapi and let them update it after logging in with Auth0.
The catch is that only that user should have read/write access to their own data.
I can't see any docs or guidance on this kind of thing. Has anyone else managed to implement this kind of thing and if so, a rough approach would be great!
Thanks!
Well, one way of the doing this is creating a OAuthUsers collection in strapi, which will hold basic details of a user like:
first_name
last_name
email
When a user registers on Auth0 and returns back to your site, you can take the basic details that were returned from the identity management platform and store it in strapi under the OAuthUsers collection.
Now, coming to your question on how to store the preferences of the user, what you can do is create another collection called preferences with following attributes:
is_dark_theme
OAuthUser (Make this a one-to-one relation with OAuthUsers collection )
Every time a logged in user updates his preferences it will first come and create an entry in this collection if not already existing. How you can check if an entry exists for a user is by using the email from the JWT token itself, that you attach as the bearer token on the API calls. I will assume, you already know how to decode a JWT token.
So a rudimentary design would be like so:
const is_dark_theme = request.body.is_dark_theme; // 1 or 0 for light theme
const user = await strapi.services.OAuthUsers.find({ email: '[email from JWT]'});
const preference = await strapi.services.preferences.find({ OAuthUser: user.id });
if(preference)
await strapi.services.preferences.update({is_dark_theme}, {id: preference.id});
else
await strapi.services.preferences.create({is_dark_theme, user: user.id});
So per this, what will happen is the user will only be able to update his own details and never be able to touch the preferences of other users as the user will only be able to pass the is_dark_theme parameter from front end and rest of the information will be taken from the JWT token.

How can a webhook identify USER_IDs?

I'm developing a webhook, and I want it to be able to #mention specific users. The simple message format specifies using the format of <users/123456789012345> to #mention a specific users. Since this is not a bot, it is not processing an incoming message and cannot pull the from the sender field, as suggested in the note on the developer site linked above.
How can I get the USER_ID of a user on my domain?
I am in the same boat as you. Trying to use a Webhook to mention a user.
If you inspect the HTML on https://chat.google.com, using web/dev tools, you can actually see user ID under tag data-member-id="user/bot/123456789012345"
Using the above I tried to form a webhook that mentioned the user (in my case another bot).
Unfortunately it didn't work. Passing in the string <users/123456789012345> please test came through to chat as a string literal.
It's strange because the html links and markup DO get interpreted. As mentioned here. Edit: so does <users/all>.
I'm leaving this here since your question asks for how to elicit the ID. While it may not be pretty, or much automatable, it helped me get the user ID at least.
Edit 2: It works, just not to mention my other bot for some reason. But using this method I was able to mention a human user :)
I use this for find the USER_ID but if you have another way let me know
Right click on the user and select inspect
Search for data-member-id this is your USER_ID
A webhook will not be able to pull the USER_ID of a user. As a workaround for this, you can create a service account and a bot that has access to the room and use the REST API spaces.members.list() and spaces.members.get() method.
Note: The bot will need to be added to the room.
Okay, so in order to get the UserID without having to do all of the things that you're trying to do here you need to use the Admin SDK API in google app script. Basically what you'll want to do is use your google app script as an intermediary for what you're trying to do. So you'll post something to google app script via their web exec functions on a deployed app and then have that app communicate to the google chat API via something like this:
var googlewebhookurl = 'https://chat.googleapis.com/v1/spaces/ASDFLKAJHEPQIHEWFQOEWNQWEFOINQ';
var options = {
'method': 'post',
'contentType': 'application/json',
'payload' : JSON.stringify({ text: "<users/000000000001> I see you!" })
}
UrlFetchApp.fetch(googlewebhookurl, options);
To start, you'll need to add the Admin SDK API to the services in your google app script services area. So click the plus next to "Services" and then select the Admin SDK API and click add to add it to the services, it winds up showing up in the list as "AdminDirectory" once it has been added to the services.
This is an image showing what it looks like once you've added it to the services.
Here is a link to the documentation for the Admin SDK API getting user information: https://developers.google.com/apps-script/advanced/admin-sdk-directory#get_user
You should be able to copy and paste that example function to get the information you're looking for regarding the user. I'm pasting the example code below in case something happens to this link:
/**
* Get a user by their email address and logs all of their data as a JSON string.
*/
function getUser() {
var userEmail = 'liz#example.com';
var user = AdminDirectory.Users.get(userEmail);
Logger.log('User data:\n %s', JSON.stringify(user, null, 2));
}
In order to get the user id, take the user variable that comes back and access user.id and voila! You have the ID you're looking for. From there just plaster it into a text message in google chat and you should be in business. I haven't gotten it to work with cards at all yet. I'm not seeing any documentation saying that it's supported in cards at all. For more information regarding chat messages and cards take a look at these:
https://developers.google.com/chat/api/guides/message-formats/basic
https://developers.google.com/chat/api/guides/message-formats/cards

How to link different authentication providers in azure mobile services

What is the best practice in azure mobile services to use different authentication providers (Facebook, Google, Windows e.t.c.) and understand that this three logins belong to the same user.
Out of the box if a user1 choose to use Facebook for authentication on his mobile phone and add some information to the app, and later he (user1) try to login with Google on his tablet, he will not see his information. Because they are two different users with different tokens. And I want to take some additional information from authentication providers (email) and has my own user table which contains email and other profile info shared for user no matter what provider he uses. How could I achieve it?
P.S. I use .NET as a backend and Windows Phone as a client
There isn't an out-of-the-box solution here. You would probably be best served by using a lookup table which maps a static user ID that you define to different identity provider IDs. Then, everywhere that you take a dependency on the user ID, you would do a lookup to match the current user identity to your static identifier. Your user ID is what gets stored everywhere else in the database.
The important detail here is that a Mobile Services token maps to a single provider identity. If you look at the user ID, it is actually provider:providerID. So we need to obtain two tokens and validate both together in order to associate two IDs.
On the client, you would have to manually prompt the user to link accounts. You would stash the current token in memory during this process, log in with the new provider, then call and API on the backend which does the association.
string existingToken = App.MobileService.CurrentUser.MobileServiceAuthenticationToken;
App.MobileService.Logout(); // allows login with new provider
await App.MobileService.LoginAsync("google");
await App.MobileService.InvokeApiAsync("associateToken", existingToken);
On the server, you need to be able to validate existingToken (the new one being implicitly validated by restricting the API to AuthorizationLevel.User)
Within that API, you can validate the token using:
IServiceTokenHandler handler = this.Request.GetConfiguration().DependencyResolver.GetServiceTokenHandler()
ClaimsPrincipal claimsPrincipal;
bool didValidate = handler.TryValidateLoginToken(existingToken, ConfigurationManager.AppSettings["MS_MasterKey"], claimsPrincipal);
You should probably also look up the user ID in your lookup table to avoid conflicts.
So overall that's a rough sketch of a possible solution. Unfortunately there isn't anything more turnkey.

MVC4 RegisterGoogleClient to request additional permissions

I am very new to MVC, really liking it just getting used to everything.
One thing i would like to implement is the google log in (done) with ability to use the response as a way to get to the calender and the contacts API.
I am trying to find something that would speak to providing an API key with the RegisterGoogleClient method found in the AuthConfi.cs file.
I have registered an app with google and have the key that would request permissions for the calender and contacts. just cant seem to find the missing link for including this key with the RegisterGoogleClien.
Ideally i will be able to get the key passed in, user will see request for permissions to the additional items and then the OAuth key provided will be usable with the GData NuGet packages.
Thanks in advance!
ps- i am guessing i need to use the overload that allows for passing in a dictionary but can not find any documentation on that as well, probably just looking in the wrong place but i have been looking for a few days.
At the moment I have the same problem as yours. I can authenticate the user (log in with google), but I cannot retrieve the user contacts. The access_token that is returned from gmail is not valid for accessing the user contacts. I need to authenticate the user, and in the same time to send my client_id and secret of the application that is registered at the google console. Then with that access_token probably I will be able to retrieve the user contacts.
RequestSettings r = new RequestSettings(app, access_token); // how to get the access_token ???
//if i have new RequestSettings(app, user_email, password); it works
ContactsRequest cRequest = new ContactsRequest(r);
Feed<Contact> feedContacts = cRequest.GetContacts(user.email);
List<string> list = new List<string>();
foreach (Contact gmailAddresses in feedContacts.Entries)
{
// Looping to read email addresses
foreach (EMail emailId in gmailAddresses.Emails)
{
list.Add(emailId.Address);
}
}

identify user accross WP8 and Win8: ANID2 vs SafeCustomerId

We have a web service that needs to indentify a user accross his devices, wp8, and win8.
On the phone side we have UserExtendedProperties.GetValue("ANID2"), which get's the anonymous microsoft id.
On Windows8 there's OnlineIdAuthenticator.AuthenticateUserAsync with UserIdentity.SafeCustomerId and other properties, though none of them look like the ANID2.
The OnlineIdAuthenticator api exists on phone, but throws NotImplementedException.
Is there any way to get a common user identifier on win8 and wp8?
Thanks
The best way I know (it's apparently the recommended way too) is to use Azure Mobile Services (http://www.windowsazure.com/en-us/home/scenarios/mobile-services/). There is a free plan that you can use.
With Mobile Services you can use the MobileServiceClient (http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.mobileservices.mobileserviceclient.aspx) to get a unique ID for each user (based on the MS account).
This code gets the user ID:
MobileServiceClient client = new MobileServiceClient(serviceUri);
MobileServiceUser user = await client.LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount);
/* The user ID contains the provider name and the ID seperated by a colon */
var userId = user.UserId.Split(':').Last();
You can find some more information here: http://msdn.microsoft.com/en-us/library/jj863454.aspx
and the SDK here: http://www.windowsazure.com/en-us/develop/mobile/developer-tools/