When signing in or signing up with aws amplify for js, it gives that error. The user pool has client secret checked and I need it like that. Is there any solution for this problem or is still a feature to be implemented?
I managed to get the sign up working based on a workaround found in stack overflow, however, the authenticateUser continues to give the same error
Here is my code
/* eslint-disable */
import { CognitoUserPool, CognitoUserAttribute, CognitoUser, AuthenticationDetails } from 'amazon-cognito-identity-js'
import crypto from 'crypto'
import * as fetchIntercept from './fetch-inceptor'
const COGNITO_SECRET_HASH_API = [
'AWSCognitoIdentityProviderService.ConfirmForgotPassword',
'AWSCognitoIdentityProviderService.ConfirmSignUp',
'AWSCognitoIdentityProviderService.ForgotPassword',
'AWSCognitoIdentityProviderService.ResendConfirmationCode',
'AWSCognitoIdentityProviderService.SignUp',
]
const CLIENT_ID = 'client_id'
const CLIENT_SECRET = 'client_secret'
const USER_POOL_ID = 'pool_id'
const hashSecret = (clientSecret, username, clientId) => crypto.createHmac('SHA256', clientSecret)
.update(username + clientId)
.digest('base64')
fetchIntercept.register({
request(url, config) {
const { headers } = config
if (headers && COGNITO_SECRET_HASH_API.includes(headers['X-Amz-Target'])) {
const body = JSON.parse(config.body)
const { ClientId: clientId, Username: username } = body
body.SecretHash = hashSecret(CLIENT_SECRET, username, clientId)
/* eslint-disable-next-line no-param-reassign */
config.body = JSON.stringify(body)
}
return [url, config]
},
})
const userPool = new CognitoUserPool({
UserPoolId: USER_POOL_ID,
ClientId: CLIENT_ID,
})
const register = (email, family_name, phone_number, address, locale, name, password) => {
const attributeList = [
new CognitoUserAttribute({ Name: 'email', Value: email }),
new CognitoUserAttribute({ Name: 'family_name', Value: family_name }),
new CognitoUserAttribute({ Name: 'phone_number', Value: phone_number }),
new CognitoUserAttribute({ Name: 'address', Value: address }),
new CognitoUserAttribute({ Name: 'locale', Value: locale }),
new CognitoUserAttribute({ Name: 'name', Value: name }),
]
// return userPool.signUp(email, password, attributeList, null, cb)
return new Promise((resolve, reject) => {
userPool.signUp(email, password, attributeList, null, (err, result) => {
if (err) {
reject((err.message || JSON.stringify(err)))
}
resolve(result)
})
})
}
const login = (email, password) => {
var authenticationData = {
Username: email,
Password: password,
};
var authenticationDetails = new AuthenticationDetails(authenticationData);
var pd = {
UserPoolId: 'userpool',
ClientId: 'clientid'
};
var up = new CognitoUserPool(pd)
var userData = {
Username: password,
Pool: up
};
var cognitoUser = new CognitoUser(userData);
return new Promise((resolve, reject) => {
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
console.log(result)
var accessToken = result.getAccessToken().getJwtToken();
resolve(result)
},
onFailure: function (err) {
console.log(err)
reject((err.message || JSON.stringify(err)))
},
})
})
}
const confirmRegister = (email, code) => {
var userData = {
Username: email,
Pool: userPool
};
var cognitoUser = new CognitoUser(userData);
return new Promise((resolve, reject) => {
cognitoUser.confirmRegistration(code, true, {
onSuccess: function (result) {
console.log(result)
resolve(result)
},
onFailure: function (err) {
console.log(err)
reject((err.message || JSON.stringify(err)))
},
})
})
}
export {
register,
login,
confirmRegister
}
I'm getting the same issue, when using Auth
class and trying to sign up a user:
Auth.signUp(email, password)
My Auth config:
Auth.configure({
identityPoolId: process.env.AWS_IDENTITY_POOL_ID,
mandatorySignIn: true,
region: process.env.AWS_REGION,
userPoolId: process.env.AWS_USER_POOL_ID,
userPoolWebClientId: process.env.AWS_USER_POOL_CLIENT_ID,
authenticationFlowType: 'USER_SRP_AUTH'
})
I looked at the sources for Auth.signUp
and down the line, but couldn't find any code that generates secretHash
and signs the request.
Is there any workaround? Is anyone working on this issue?
Got the same error. It looks like Amplify currently doesn't support client with secret. Could someone please confirm?
@ngocketit, client secret is currently not supported, correct. I'll mark this as a feature request.
Any eta?
Also looking for an update on this.
I'll add myself to the list of people looking for an update on this
+1
+1 as well
1+
+1 as well
+1
found workaround here
basically when creating new client app we need to uncheck the "Generate client secret"
+1
+1
+1 (or +233323232323 - if that can speed up the process to support this)
+1 ... it works with amplify auth add but this adds two app clients (one with client secret and one without) the app client with no secret is added to aws-exports.js. this is not a solution. just an fyi lol
+1 🤷♂️
+1
Still no support for client secret, (except the uncheck way that sir @FadiAboMsalam mention above)
+1...
+1....
+1
+1
any update on this yet?
Hi everyone,
Because this is an important & popular issue to the community, I wanted to update everyone that we're continuing to investigate this. Here are our next steps:
We did meet with the Cognito service team and learned a bit more about client secrets:
The client secret is primarily for server-to-server communication: if it's bundled in the client, then anyone can access unintended resources unintentionally.
(This isn't specific to Cognito, as others like Auth0 has a dedicated page on this topic)
Since Amplify JS is intended for client-side usage, this raises security concerns that can have an unintentional impact.
Cognito's docs mention something similar:
It is your responsibility to secure any app client IDs or secrets so that only authorized client apps can call these unauthenticated APIs.
...
If a secret is created for the app, the secret must be provided to use the app. Browser-based applications written in JavaScript may not need an app with a secret.
amplify add auth
is the preferred way of creating pools, and solves for many of these issues.
For those with this issue, has unchecking this box resolved the issue?
Or is there a use-case that you can provide more information on why this doesn't fit your needs?
Thanks, and please keep the feedback coming!
We'd like to understand more what situations _don't_ allow for unchecking the _Generate client secret_ box:
Can you share what scenarios require the client secret so that we can better accommodate them?
Thanks!
+1
actually there is no sense for further discussion. By definition secret shouldn't be exposed. This is intended behavior after all.
We're still looking to learn more about circumstances that aren't resolved by unchecking the "Generate client secret" button:
https://github.com/aws-amplify/amplify-js/issues/1368#issuecomment-564311714
This issue has been automatically closed because of inactivity. Please open a new issue if are still encountering problems.
This is still an issue when for development purposes on a client app that in normal situations should use a secret, where one wants to create a dev-user from a local environment in that pool.
@ronkorving Thanks for the response. I don't fully understand your example, can you provide more details?
...in normal situations should use a secret
For those situations, is "Generate client secret" checked/unchecked?
https://github.com/aws-amplify/amplify-js/issues/1368#issuecomment-564311714
I'm doing local development, with a user pool on my development account.
Generate client secret is checked, because that's my normal flow. I want to be able to create test users quickly though, not having to go through any confirmation process. The user is just for development, but I do want the user pool client's auth flow to be identical to production.
What I did now as a workaround was to create a script that creates a temporary client on my pool that does not have a secret, then create my test-user, then remove that temporary client. It solves the problem.
I too see a need for this. In my case I have an API Gateway fronting a NodeJS Lambda. My API acts as a proxy for Cognito - abstracting it away so clients only interact with my API surface area.
Because of this, my Lambda handles the signUp and auth calls to Cognito on behalf of the user. The client devices POST their credentials to my API and I forward them along to Cognito. In this use-case a ClientSecret would be desirable between my Lambda and Cognito and not just a ClientId.
I suppose I should clarify... My use-case is the aws-sdk and not Amplify-js... I 100% agree Amplify itself should not support this as client-side deployments should not include secrets. Secrets are typically used for server to server authorization. I believe aws-sdk provides this when I look at the docs.
@ericclemmons
Amazon Cognito Hosted UI if it supports the authorization code grant type. But I need to replace the Amazon Cognito Hosted UI by my Custom UI and use it as an IDP in my Company, and some of those applications only allow configuring the authorization code grant type.
What alternative do I have?
Is it possible to validate the secret with a lambda trigger?
@ealiaga There are a few options available via Custom Cognito Lambda Triggers, but for more, I'd recommend starting a new Discussion.
Hi @ericclemmons , I want to login my amplify app with a cognito appclient with secret key. There is required for me, because i configured an elasticsearch instances with cognito, and automatically thats created an appclient with secretkey. So i want to load a dashboard kibana in my amplify app, but i received de same error Unable to verify secret hash for client.
I can't create another appclient without secret key, because elasticsearch use another with this.
https://github.com/aws-amplify/amplify-js/discussions/7063
Most helpful comment
Hi everyone,
Because this is an important & popular issue to the community, I wanted to update everyone that we're continuing to investigate this. Here are our next steps:
We did meet with the Cognito service team and learned a bit more about client secrets:
The client secret is primarily for server-to-server communication: if it's bundled in the client, then anyone can access unintended resources unintentionally.
(This isn't specific to Cognito, as others like Auth0 has a dedicated page on this topic)
Since Amplify JS is intended for client-side usage, this raises security concerns that can have an unintentional impact.
Cognito's docs mention something similar:
amplify add auth
is the preferred way of creating pools, and solves for many of these issues.For those with this issue, has unchecking this box resolved the issue?
Or is there a use-case that you can provide more information on why this doesn't fit your needs?
Thanks, and please keep the feedback coming!