<@U01JVDKASAC> while trying to add google auth, My...
# help
k
@Frank while trying to add google auth, My app is breaking in the process. I am making a Post request to create a note. This is the function for creating a note:
Copy code
export 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"
Copy code
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
Copy code
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
f
@Kenny just to clarify, the GET route works but the POST route doesnt?
k
It does now 😗 I Forgot to set authentication headers in React.