Kenny
06/02/2022, 7:59 PMexport const main = handler(async (event) => {
const data = JSON.parse(event.body);
const params = {
TableName: process.env.TABLE_NAME,
Item: {
userId: event.requestContext.authorizer.jwt.claims.sub,
noteId: uuid.v1(),
content: data.content,
attachment: data.attachment,
createdAt: Date.now(),
},
};
await dynamoDB.put(params);
return params.Item;
});
I am setting the sub event*.*_requestContext_*.*_authorizer_*.*_jwt_*.*_claims_*.*_sub_
as the userId. When making this request I get a 401 Error saying I am unauthorized. But when I make a get request I don't get an error. function for the get request "get a list of notes"
export const main = handler(async (event) => {
const params = {
TableName: process.env.TABLE_NAME,
KeyConditionExpression: "userId = :userId",
ExpressionAttributeValues: {
":userId": event.requestContext.authorizer.jwt.claims.sub,
},
};
const result = await dynamoDB.query(params);
return result.Items;
});
and this is my full API and AUTH stack
import * as iam from "aws-cdk-lib/aws-iam";
import * as cognito from "aws-cdk-lib/aws-cognito";
import * as apigAuthorizers from "@aws-cdk/aws-apigatewayv2-authorizers-alpha";
import { Auth, Api, use } from "@serverless-stack/resources";
import { StorageStack } from "./StorageStack";
export function AuthApiStack({ stack, app }) {
const { bucket } = use(StorageStack);
const { table } = use(StorageStack); //This new ApiStack references the table resource from the StorageStack that we created previously.
const auth = new Auth(stack, "Auth", {
login: ["email"],
cdk: {
userPoolClient: {
supportedIdentityProviders: [
cognito.UserPoolClientIdentityProvider.GOOGLE,
cognito.UserPoolClientIdentityProvider.COGNITO,
],
oAuth: {
callbackUrls: [
app.stage === "prod"
? "prodDomainNameUrl"
: "<http://localhost:3000>",
],
logoutUrls: [
app.stage === "prod"
? "prodDomainNameUrl"
: "<http://localhost:3000>",
],
},
},
},
});
if (!process.env.GOOGLE_CLIENT_ID || !process.env.GOOGLE_CLIENT_SECRET)
throw new Error("Please set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET");
// Create a Google OAuth provider
const googleProvider = new cognito.UserPoolIdentityProviderGoogle(
stack,
"Google",
{
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
userPool: auth.cdk.userPool,
scopes: ["profile", "email", "openid"],
attributeMapping: {
email: cognito.ProviderAttribute.GOOGLE_EMAIL,
givenName: cognito.ProviderAttribute.GOOGLE_GIVEN_NAME,
familyName: cognito.ProviderAttribute.GOOGLE_FAMILY_NAME,
profilePicture: cognito.ProviderAttribute.GOOGLE_PICTURE,
},
}
);
// Create a Facebook OAuth provider
// attach the created providers to our userpool
auth.cdk.userPoolClient.node.addDependency(googleProvider);
const domain = auth.cdk.userPool.addDomain("AuthDomain", {
cognitoDomain: {
domainPrefix: `${app.stage}-notes-auth-domain`,
},
});
const api = new Api(stack, "Api", {
// defaults: {
// authorizer: "iam",
// function: {
// permissions: [table], //We are giving our API permission to access our DynamoDB table
// environment: {
// TABLE_NAME: table.tableName, //We'll need this to query our table.
// STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
// },
// },
// },
authorizers: {
userPool: {
type: "user_pool",
cdk: {
authorizer: new apigAuthorizers.HttpUserPoolAuthorizer(
"Authorizer",
auth.cdk.userPool,
{
userPoolClients: [auth.cdk.userPoolClient],
}
),
},
},
},
defaults: {
authorizer: "userPool",
function: {
permissions: [table], //We are giving our API permission to access our DynamoDB table
environment: {
TABLE_NAME: table.tableName, //We'll need this to query our table.
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
},
},
},
routes: {
"POST /notes": "functions/create.main",
"GET /notes/{id}": "functions/get.main",
"GET /notes": "functions/list.main",
"PUT /notes/{id}": "functions/update.main",
"DELETE /notes/{id}": "functions/delete.main",
"POST /billing": "functions/billing.main",
},
});
auth.attachPermissionsForAuthUsers([
api,
new iam.PolicyStatement({
actions: ["s3:*"],
effect: iam.Effect.ALLOW,
resources: [
bucket.bucketArn + "/private/${<http://cognito-identity.amazonaws.com:sub|cognito-identity.amazonaws.com:sub>}/*",
],
}),
]);
stack.addOutputs({
ApiEndpoint: api.url,
AuthDomain: domain.domainName,
Region: app.region,
UserPoolId: auth.userPoolId,
IdentityPoolId: auth.cognitoIdentityPoolId,
UserPoolClientId: auth.userPoolClientId,
});
return { auth, api, domain };
}
I am sending this request payload {content: "jhgghj", attachment: null}
from my frontend React to the backend, so I first thought it could be denying access to s3 but clearly I am setting it using iam.PolicyStatement and auth.attachPermissionsForAuthUsers
Frank
Kenny
06/03/2022, 6:08 PM