use react-native-google-signin with custom domain - react-native

I have google signin in a web and a react native app (android and ios).
I can login in both platforms but the token data differs (and because of that the app's one is invalid)
I've looked the docs and try multiple params in different fields but no success
app configuration:
// scopes: ['profile', 'email'], // it doesn't matter if commented or not
// webClientId: '**********.apps.googleusercontent.com', //
// offlineAccess: false, // if you want to access Google API on behalf of the user FROM YOUR SERVER
// hostedDomain: 'https://securetoken.google.com/**********', // if I use this, (or other strings I tried, cant login
// loginHint: '',
forceConsentPrompt: true,
accountName: '**********', //
// accountName: '**********:android:**********', // nothing happens
iosClientId: '**********.apps.googleusercontent.com', // is different from the android one
web configuration (with firebase):
apiKey: "**********",
authDomain: "**********.firebaseapp.com",
databaseURL: "https://**********.firebaseio.com",
projectId: "**********",
storageBucket: "",
2: "**********",
appId: "**********:web:**********"
web token infromation:
{
"iss": "https://securetoken.google.com/**********",
"aud": "**********",
"sub": "**********",
"email": "**********#gmail.com",
"email_verified": true,
"name": "**********",
"picture": "**********",
"auth_time": 1568973313,
"user_id": "**********",
"sign_in_provider": "google.com",
"iat": **********,
"exp": **********,
"firebase": {
"identities": {
"google.com": ["**********"],
"email": ["**********#gmail.com"]
}
}
}
app token information:
{
"iss": "https://accounts.google.com",
"azp": "**********.apps.googleusercontent.com",
"aud": "**********.apps.googleusercontent.com",
"sub": "**********",
"email": "**********#gmail.com",
"email_verified": true,
"name": "**********",
"picture": **********",
"given_name": "**********",
"family_name": "**********",
"locale": "es",
"iat": **********,
"exp": **********
}

I manage to solve it using also firebase (firebase.initializeApp(/params/)) , first I do a login with react-native-google-signin and then, if success, login with firebase to obtain the correct token:
// login with google, on web is unnecesary, to use native interface
const { user } = await GoogleSignin.signIn();
const googleTokens = await GoogleSignin.getTokens();
// login with firebase, to get the correct token
const credential = firebase.auth.GoogleAuthProvider.credential(googleTokens.idToken, googleTokens.accessToken);
const auth = firebase.auth();
await auth.signInWithCredential(credential);
// get firebase token and user email
const idToken = auth.currentUser && (await auth.currentUser.getIdToken(true));
const email = user && user.email;
// login into my back
if (idToken && email) googleLogIn(email, idToken);

Related

AWS Cognito External User Pool Identity Provider(OIDC)

I'm using Cognito App Client integration with external provider(Twitch)
User authentication works fine, but as code from auth server is consumed by Cognito, I'm not sure how should I send Twitch requests with token, which I'd normally get from twitch I Cognito wouldn't consume this code. I only have Cognito code, which I can use in https://{my-domain}/oauth2/token requests in exchange for Cognito tokens. request returns id_token, access_token and refresh_token, which decoded look like
id token
{
"at_hash": "yTNkeTAqzqcXCYi3yLL2Pw",
"sub": "3cfba641-4058-475f-9818-17291175fd31",
"cognito:groups": [
"us-east-1_xxxxxxxxxxxx"
],
"iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxxxxxxxxx",
"cognito:username": "xxxxxxxxxxxx",
"preferred_username": "xxxxxxxxxxxx",
"nonce": "SxxlipCDVbXbcXa1H7Uf9_nM0uOurAAObUVCyreBDDux99QoAngUoiGdE0me-0Zon6fEVLLTSqD4EN1Y6_lFm48MaoBaxyywZCQKOT70gfQEfkuhlsjImJd1ko3qH3QKdlmvWSPCUZoACPYNSgR364VPELyQTVMkRTCt9eYROag",
"aud": "35l1cn53cnj9sv1ndu8u01amk0",
"identities": [
{
"userId": "xxxxxxxxxxxx",
"providerName": "xxxxxxxxxxxx",
"providerType": "OIDC",
"issuer": null,
"primary": "true",
"dateCreated": "1588191000072"
}
],
"token_use": "id",
"auth_time": 1588191003,
"exp": 1588194603,
"iat": 1588191003
}
access token
{
"sub": "3cfba641-4058-475f-9818-17291175fd31",
"cognito:groups": [
"us-east-1_xxxxxxxxxxxx"
],
"token_use": "access",
"scope": "aws.cognito.signin.user.admin phone openid profile email",
"auth_time": 1588191003,
"iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxxxxxxxxx",
"exp": 1588194603,
"iat": 1588191003,
"version": 2,
"jti": "55863213-c764-4b07-a386-a9c93d14e4b2",
"client_id": "xxxxxxxxxxxx",
"username": "xxxxxxxxxxxx"
}
How can I get user token to call Twitch API (for example GET https://api.twitch.tv/helix/users endpoint with authorized user's token)
CAUTION - Doing it incorrectly, you expose sensitive attributes to client.
You need to create 2 versions of attributes - custom and dev:custom, map oidc provider attributes to custom ones (looks like dev:custom aren't mappable), then in TokenGeneration_HostedAuth trigger you need to get these custom attributes, set dev:custom ones, then delete customs.
Seems like a tweak, but I don't see another way of doing it and keeping tokens safe.
Solution for that is to create custom attributes in your user pool, then map these attributes for identity provider. Looks something like:
'custom:refresh_token': refresh_token
'custom:id_token': id_token
'custom:access_token': access_token
Cloudformation template for that:
user pool
....
Schema: [
{
AttributeDataType: 'String',
DeveloperOnlyAttribute: true,
Mutable: true,
Name: 'refresh_token',
Required: false,
},
{
AttributeDataType: 'String',
DeveloperOnlyAttribute: true,
Mutable: true,
Name: 'access_token',
Required: false,
},
{
AttributeDataType: 'String',
DeveloperOnlyAttribute: true,
Mutable: true,
Name: 'id_token',
Required: false,
},
{
AttributeDataType: 'String',
Mutable: true,
Name: 'refresh_token',
Required: false,
},
{
AttributeDataType: 'String',
Mutable: true,
Name: 'access_token',
Required: false,
},
{
AttributeDataType: 'String',
Mutable: true,
Name: 'id_token',
Required: false,
},
],
....
user pool identity provider
....
AttributeMapping: {
'custom:refresh_token': 'refresh_token',
'custom:access_token': 'access_token',
'custom:id_token': 'id_token',
},
....

Auth.currentAuthenticatedUser not loading name and family name attributes (and others) from Cognito

I'm using the Auth.currentAuthenticatedUser method to retrieve the attributes recorded for the logged user from AWS Cognito - but only basic atributes are showing. The ones I want are "name" and "family name", but they don't seem to be loaded in the Promise.
This is only the beggining, but I'm concerned as I will want to retrieve other attributes which are not showing up, like user picture, for instance.
Tried to use currentAuthenticatedUser and currentUserInfo with the same results.
async componentDidMount() {
await Auth.currentAuthenticatedUser({bypassCache: true})
.then ( user => this.setUserInfo( user ) )
.catch( err => console.log(err))
}
CognitoUser {
"Session": null,
"attributes": Object {
"email": "r...#gmail.com",
"email_verified": true,
"phone_number": "+5...",
"phone_number_verified": false,
"sub": "246e9...",
},
"authenticationFlowType": "USER_SRP_AUTH",
"client": Client {
"endpoint": "https://cognito-idp.us-east-2.amazonaws.com/",
"userAgent": "aws-amplify/0.1.x react-native",
},
"deviceKey": undefined,
"keyPrefix": "CognitoIdentityServiceProvider.12ddetjn0c0jo0npi6lrec63a7",
"pool": CognitoUserPool {
"advancedSecurityDataCollectionFlag": true,
"client": Client {
"endpoint": "https://cognito-idp.us-east-2.amazonaws.com/",
"userAgent": "aws-amplify/0.1.x react-native",
},
"clientId": "12ddetjn0c0jo0npi6lrec63a7",
"storage": [Function MemoryStorage],
"userPoolId": "us-east...",
},
"preferredMFA": "NOMFA",
"signInUserSession": CognitoUserSession {
"accessToken": CognitoAccessToken {
"jwtToken": "e...oJPg",
"payload": Object {
"auth_time": 1565137817,
"client_id": "1...6lrec63a7",
"event_id": "c3...-4bd9-ad42-200f95f9921c",
"exp": 15...2,
"iat": 156...5872,
"iss": "https://cognito-idp.us-east-2.amazonaws.com/us-east-...",
"jti": "5483e...544149c42e58",
"scope": "aws.cognito.signin.user.admin",
"sub": "246e93...f4d8e6f4725b",
"token_use": "access",
"username": "r...f",
},
},
"clockDrift": -2,
"idToken": CognitoIdToken {
"jwtToken": "eyJraWQiOiJk...",
"payload": Object {
"aud": "12ddetjn0c0j..rec63a7",
"auth_time": 1565137817,
"cognito:username": "r..",
"email": "r..#gmail.com",
"email_verified": true,
"event_id": "c3ae..200f95f9921c",
"exp": ..2,
"iat": ..2,
"iss": "https://cognito-idp.us-east-2.amazonaws.com/us-east-..",
"phone_number": "+5...3",
"phone_number_verified": false,
"sub": "246e937..f4d8e6f4725b",
"token_use": "id",
},
},
"refreshToken": CognitoRefreshToken {
"token": "eyJjd...",
},
},
"storage": [Function MemoryStorage],
"userDataKey": "CognitoIdentityServiceProvider.12ddetjn0....userData",
"username": "r...ff",
}
To get all user attributes, you may be looking for the Auth.userAttributes() function. To use this you want something like this code:
const authUser = await Auth.currentAuthenticatedUser();
const attributes = await Auth.userAttributes(authUser);
// the next line is a convenience that moves the attributes into
// the authUser object
attributes.forEach((attr) => {
authUser.attributes[attr.Name] = attr.Value;
});
If you're still not getting the attributes you need, take a look here, and you can see that you can enable the reading of other attributes from the Amplify command line.
So, in the root of your project:
Type "amplify update auth" at the console.
Select "Walkthrough the auth configurations"
Step through making all the same selections as you've done before.
When it asks, "Do you want to specify the user attributes this app can read and write?" it's "Y", and then you select the attributes you want to be able to read.
When you finish the wizard, use "amplify push auth"
When that's completed, try re-running.
As an alternative to steps 1-4 above, you can also edit cli-inputs.json in the amplify\backend\auth<your auth config name> directory. It's in "userpoolClientReadAttributes". Simply add the attributes you would like to this array (e.g. "name").
This answer was verified with amplify CLI version 8.1.0.

Oauth 2.0: I can't get profile info from Google "token info endpoint" by using id_token

I'm trying to get user info (profile,email) from Google by using OAuth 2.0.
But "token info endpoint" did not return profile info even though I set "profile" to scopes.
I followed the doc of Google sign-in for iOS. (https://developers.google.com/identity/sign-in/ios/backend-auth)
I couldn't figure out why this end point doesn't return profile info as I expected.
First I get Token by oauth2.0 (as a test, I got token using Rails)
def gmail
require 'oauth2'
client = OAuth2::Client.new(
'Client-id',
'client-secret',
{
site: 'https://accounts.google.com/',
authorize_url: 'o/oauth2/auth',
}
)
redirect_to client.auth_code.authorize_url(
redirect_uri: 'http://localhost:3000/google_signup',
scope: 'email profile',
)
end
token = client.auth_code.get_token(
params[:code],
redirect_uri: 'http://localhost:3000/gmail_signup',
and I get id_tokenfrom this token.
then, send GET request to "token info endpoint".
"https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=id_token"
but response didn't contain profile info.
{
"azp": "azp",
"aud": "aud",
"sub": "sub",
"email": "email#gmail.com",
"email_verified": "true",
"at_hash": "at_hash",
"exp": "TIMESTAMP",
"iss": "accounts.google.com",
"iat": "iat",
"alg": "alg",
"kid": "kid"
}
The response was supposed to be like this.
{
// These six fields are included in all Google ID Tokens.
"iss": "https://accounts.google.com",
"sub": "110169484474386276334",
"azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
"aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com",
"iat": "1433978353",
"exp": "1433981953",
// These seven fields are only included when the user has granted the "profile" and
// "email" OAuth scopes to the application.
"email": "testuser#gmail.com",
"email_verified": "true",
"name" : "Test User",
"picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg",
"given_name": "Test",
"family_name": "User",
"locale": "en"
}

Identity Manager throws 401 unauthorized

I am using following configuration for my Identity Manager, everytime I pass my access token - it throws 401 (Unauthorized)
app.Map("/admin", adminApp =>
{
var factory = new IdentityManagerServiceFactory();
factory.ConfigureSimpleIdentityManagerService("AspId");
var securityConfig = new ExternalBearerTokenConfiguration
{
Issuer = "https://localhost:44333/core",
Audience = "https://localhost:44333/core/resources",
Scope = "idmgr",
SigningCert = Certificate.Get(),
};
adminApp.UseIdentityManager(new IdentityManagerOptions()
{
Factory = factory,
SecurityConfiguration = securityConfig
});
});
My acesss token which I pass as AUthorization Bearer looks like
{
"iss": "https://localhost:44333/core",
"aud": "https://localhost:44333/core/resources",
"exp": 1449995870,
"nbf": 1449995510,
"client_id": "roclient",
"scope": [
"email",
"idmgr",
"openid",
"phone",
"profile"
],
"sub": "58067d52-64bf-4447-a928-d3a1316bd677",
"auth_time": 1449995509,
"idp": "idsrv",
"role": [
"admin",
"IdentityManagerAdministrator"
],
"amr": [
"password"
]
}
Is it something I am not doing right ?

Using the access token with the SkyDrive API

I have been trying to get access to the json result with the following link:
https://apis.live.net/v5.0/file.a4423f3123801749.A4423F3123801749!418
But as you can see by clicking on it yourself, you need an access token.
I already have an access token, but it only lasts for 3600 seconds (1 hour).
Is there a way to get the results of the link (the json shown below) without the access token expiring? I know there is a refresh token, but I am unsure how to use it.
{
"id": "file.a4423f3123801749.A4423F3123801749!418",
"from": {
"name": "Andrew Wong",
"id": "a4423f3123801749"
},
"name": "Mod Permissions.xlsx",
"description": "",
"parent_id": "folder.a4423f3123801749.A4423F3123801749!129",
"size": 89956,
"upload_location": "https://apis.live.net/v5.0/file.a4423f3123801749.A4423F3123801749!418/content/",
"comments_count": 0,
"comments_enabled": true,
"is_embeddable": true,
"source": "https://hvbqwg.dm2302.livefilestore.com/y2m6t-kEOaAd1qXi2n4cvNuVCMqU2Is3Ft_7g7UGM1h6Ib8oyGSFzT70rT3F3mz5PFsrzUDkyAfhYoh1YIZWNY3INmCIKheJpZWoUVTvz-xh5I/Mod%20Permissions.xlsx?psid=1",
"link": "https://skydrive.live.com/redir.aspx?cid=a4423f3123801749&page=view&resid=A4423F3123801749!418&parid=A4423F3123801749!129",
"type": "file",
"shared_with": {
"access": "Public"
},
"created_time": "2014-01-16T07:06:41+0000",
"updated_time": "2014-01-16T07:14:51+0000",
"client_updated_time": "2014-01-16T07:14:51+0000"
}
Do a post to https://login.live.com/oauth20_token.srf to convert your refresh_token to an access_token. Read more in MS documentation bullet #6.
Here are a sample node.js code
var options,request;
request = require('request');
options = {
url: 'https://login.live.com/oauth20_token.srf',
form: {
client_id: YOUR CLIENT_ID,
redirect_uri: YOUR REDIRECT_URI,
client_secret: YOUR CLIENT_SECRET,
refresh_token: YOUR REFRESH_TOKEN,
grant_type: 'refresh_token'
},
headers: {
'Accept': 'application/json'
}
};
request.post(options, function(err, response, data) {
});