At my current project, we are using Auth0 as our Identity Provider. The current architecture is just a ReactJS app supported by a couple of APIs. Each API requires different combinations of Authorization Scopes, but basically they will require Customer Role, Provider Role or any authenticated user. We were using Username-Password-Authentication so far and now we are integrating Social logins (such as Facebook, Google and Apple).
In order to achieve so, we are using Authorization Code flow, so the BE constructs the Authorize URL (including Callback URL, scopes, etc) that the FE then uses. After the user has authenticated against the Social Provider, the Callback URL is called, we exchange the code for an access_token that is ultimately returned to the FE. So far so good.
https://{domain}.auth0.com/authorize?
response_type=code&
client_id={clientId}&
audience={audience}&
connection=facebook&
state={ramdom_value}&
redirect_uri={callbackUrl}&
scope=offline_access openid scope:customer
And here is where some issues arise.
Firstly, after exchanging the Authentication Code for an access_token, the token does not include the scopes in it, so the user cannot access the APIs. I had to create a custom rule that adds the Customer role, like this:
function (user, context, callback) {
var count = context.stats && context.stats.loginsCount ? context.stats.loginsCount : 0;
if (count > 1 || (context.connection !== 'facebook' && context.connection !== 'google-oauth2' && context.connection !== 'apple')) {
return callback(null, user, context);
}
var ManagementClient = require('auth0@2.17.0').ManagementClient;
var management = new ManagementClient({
token: auth0.accessToken,
domain: auth0.domain
});
management.assignRolestoUser(
{ id : user.user_id},
{ "roles" :["rol_Msm9ykmstuK09r9s"]},
function (err) {
if (err) {
callback(err);
} else {
callback(null, user, context);
}
}
);
}
I don't really understand why I need to create the rule in order to get a valid access_token.
Secondly, there are two possible roles for users, Customers and Providers. For now, we are only allowing customers to use Social Logins, but eventually we will need to support also Providers. There is no way for us to detect what kind of user is actually logging in within that rule. So my question here would be how to solve it.
My final goal is to allow users (both Customers and Providers) to log in using Social Connections and have each of them with the roles they really require. Of course, I need to get a valid access_token so that users can then interact with our APIs.
Any thoughts or comments? What am I missing?
I came up with an elegant solution after all.
The approach I took was:
Create a Custom Rule that assigns both roles (Customer and Provider) only and only if:
1.1. This is the first login for this user
1.2. The connection type is either facebook
or google-oauth2
or apple
When creating the URL for login, include only the scopes required based on the user role required. In addition, the callback url will include the user role in it, e.g. https://server/{platform}/callback/{role}
In the callback endpoint, remove the roles that are not required using the Auth0 Management API /api/v2/users/{id}/roles
This solution is a bit tricky, but works with relatively small coding and effort.