Guy Shechter
08/31/2021, 3:47 AMFrank
Guy Shechter
08/31/2021, 2:40 PMthis.auth = new sst.Auth(this, 'auth', {
cognito: {
userPool: {
userPoolName: this.scope.logicalPrefixedName('userPool'),
}
},
google: {
clientId:
'<http://xxx-xxx.apps.googleusercontent.com|xxx-xxx.apps.googleusercontent.com>',
},
})
Guy Shechter
08/31/2021, 3:13 PMFrank
Auth
construct is meant to tie google into identity pool. I think your setup is different. You are looking to tie google into the user pool.Frank
Guy Shechter
09/02/2021, 12:29 AMthis.cognitoDomainPrefix = `${this.scope.stage}example`
this.cognitoUserPool = new cognito.UserPool(this, 'userPool', {
userPoolName: this.scope.logicalPrefixedName('userPool'),
lambdaTriggers: {
preAuthentication: emailDomainPreAuthorizer
}
})
this.cognitoUserPool.addDomain('custom-domain-cognito',
{
cognitoDomain:
{
domainPrefix: this.cognitoDomainPrefix
}
}
)
this.UserPoolIdentityProviderGoogle = new cognito.UserPoolIdentityProviderGoogle(this, 'google-provider', {
clientId: '<http://123123123123-123456abcdef.apps.googleusercontent.com|123123123123-123456abcdef.apps.googleusercontent.com>',
clientSecret: 'XXXXXXX',
userPool: this.cognitoUserPool,
attributeMapping: {
email: cognito.ProviderAttribute.GOOGLE_EMAIL
},
scopes: ['profile', 'email', 'openid']
})
const callbackUrls = this.scope.stage === 'dev' ? ['<http://localhost:3000>', '<https://dev.example.com>'] : ['<https://staging.example.com>', '<https://www.example.com>']
this.cognitoUserPoolClient = new cognito.UserPoolClient(this, 'userPoolClient', {
userPool: this.cognitoUserPool,
supportedIdentityProviders: [cognito.UserPoolClientIdentityProvider.GOOGLE],
userPoolClientName: `${this.scope.stage}googleClient`,
oAuth: {
callbackUrls
}
})
this.cognitoUserPoolClient.node.addDependency(this.UserPoolIdentityProviderGoogle)
Then passed the following to the SPA:
<http://this.site|this.site> = new sst.ReactStaticSite(this, 'ReactSite', {
path: 'frontend',
// Pass in our environment variables
environment: {
REACT_APP_API_URL: this.customApiDomainUrl,
REACT_APP_REGION: this.scope.region,
REACT_APP_USER_POOL_ID: this.cognitoUserPool.userPoolId,
REACT_APP_USER_POOL_CLIENT_ID: this.cognitoUserPoolClient.userPoolClientId,
REACT_APP_COGNITO_DOMAIN: `${this.cognitoDomainPrefix}.auth.${this.scope.region}.<http://amazoncognito.com|amazoncognito.com>`,
REACT_APP_CALLBACK: `https://${this.scope.stage}.${process.env.DOMAIN_NAME}`
},
customDomain: {
hostedZone: process.env.DOMAIN_NAME,
domainName: `${this.scope.stage === 'prod' ? 'www' : this.scope.stage}.${process.env.DOMAIN_NAME}`,
}
})
Guy Shechter
09/02/2021, 12:31 AMconst emailDomainPreAuthorizer = new sst.Function(this, 'Email-Domain-Authorizer', {
handler: 'src/auth/preauth-domain.handler',
runtime: lambda.Runtime.NODEJS_14_X,
environment: {
ALLOWED_USER_DOMAIN: process.env.ALLOWED_USER_DOMAIN
},
securityGroups: [this.securityGroup],
vpcSubnets: this.subnets,
vpc: this.vpc
})
and for preauth-domain.js
, I found an example on the interweb:
exports.handler = async (event, context, callback) => {
const userEmailDomain = event.request.userAttributes.email.split('@')[1]
const allowedDomain = process.env.ALLOWED_USER_DOMAIN
if (userEmailDomain === allowedDomain) {
callback(null, event)
} else {
const error = new Error('Cannot authenticate users from domains different from ' + allowedDomain)
callback(error, event)
}
}
Frank
Frank