I have an Amplify app using Cognito for userpool authentication. Once a user has signed up and used the code sent via email (all Cognito functionality), they are passed to a custom form where additional information is captured. On submit a lambda function is executed that should:
The lambda function deploys nicely as part of my sandbox, and permissions have been granted for allow.resource(createAccount).to(["manageGroups", "addUserToGroup", "manageGroupMembership"])}
as well as modifying DynamoDB data. However as soon as either CognitoIdentityProviderClient
or await client.models.User.create(user)
are hit from inside the lambda function, I get the following error from Graphql API No federated jwt
. Example of code used:
const user = {
userId: userId,
...
};
const { data, errors} = await client.models.User.create(user); <-- `No federated jwt` error thrown here
Or
const cognitoClient = new CognitoIdentityProviderClient();
const userGroup = {
GroupName: `GroupName`,
Precedence: 1,
Description: `Description`,
UserPoolId: userPoolId,
};
const createCommand = new CreateGroupCommand(userGroup);
const response = await cognitoClient.send(createCommand ); <-- `No federated jwt` error thrown here
The examples in the Amplify Gen 2 documentation don't cover this scenario. What am I missing?
If the User data model is set to only allow owner, or authenticated users to create then you need to set the authMode for your client.models.user.create command to identityPool and pass in the user's jwtToken. The token can be retrieved from the header if you're using APIGateway to call the lambda. If you're not using API gateway you'll have to pass it in yourself.
Here's an example data
const schema = a.schema({
User: a
.model({
name: a.string(),
group: a.string(),
})
.identifier(["User"]),
})
.authorization((allow) => [allow.owner()]);
export type Schema = ClientSchema<typeof schema>;
export const data = defineData({
schema,
authorizationModes: {
defaultAuthorizationMode: "identityPool",
},
});
And here's an example lambda called using APIGateway
export const handler: APIGatewayProxyHandler = async (event) => {
let jwtToken: string | undefined;
// Method 1: From JWT authorizer claims
jwtToken = event.requestContext.authorizer?.jwt?.claims?.['id_token'] as string;
// Method 2: From Authorization header (if token is passed in header)
if (!jwtToken) {
const authHeader = event.headers['Authorization'];
jwtToken = authHeader;
}
if (jwtToken) {
console.log('jwtToken found:', jwtToken);
// Use the jwtToken as needed
} else {
console.log('jwtToken not found in the request');
}
const client = generateClient<Schema>({
authMode: "identityPool",
authToken: jwtToken,
});
const createStoryResult = await client.models.User.create({
name: "foo",
group: "Bar",
},
{
authMode: "identityPool",
authToken: jwtToken,
});