https://serverless-stack.com/ logo
#help
Title
# help
d

Dan Russell

01/12/2022, 4:57 PM
Hey I am having trouble with what I think is a CORS problem. I set up an API with a custom lambda authorizer for some routes and have that working in Postman. When I try the same request in the react site I get Cors errors. I have tried setting the cors setting on the api to allow authorization headers and origins from localhost but can't seem to find a configuration that works. I dont know if its a problem with the authorizer, the API, or maybe the zxios call but if anyone has them working I would love to see an example. Api: (this was me trying every header I could think of but it also failed with cors on default)
Copy code
const authorizer = new HttpLambdaAuthorizer({  
      authorizerName: "QuizAuthorizer",
      responseTypes: [HttpLambdaResponseType.IAM],
      handler: new sst.Function(this, "Authorizer", {
        handler: "src/authorizer.main",
      }),
      resultsCacheTtl: Duration.seconds(0)
    });

    const api = new sst.Api(this, `api`, {
      defaultAuthorizationType: sst.ApiAuthorizationType.CUSTOM,
      defaultAuthorizer: authorizer,
      defaultFunctionProps: {
        srcPath: "src/",
        environment: {
          NODE_ENV: process.env.NODE_ENV || 'development',
          STAGE: scope.stage,
        },
      },
      cors: {
        allowHeaders: [
          'X-Amz-Date',
          'X-Api-Key',
          'X-Amz-Security-Token',
          'X-Requested-With',
          'X-Auth-Token',
          'Referer',
          'User-Agent',
          'Origin',
          'Content-Type',
          'Authorization',
          'Accept',
          'Access-Control-Allow-Methods',
          'Access-Control-Allow-Origin',
          'Access-Control-Allow-Headers'],
        allowMethods: [
          CorsHttpMethod.GET, 
          CorsHttpMethod.PUT, 
          <http://CorsHttpMethod.POST|CorsHttpMethod.POST>,
          CorsHttpMethod.DELETE, 
          CorsHttpMethod.OPTIONS, 
        ],
        allowOrigins: ['<http://localhost:3000>'],
        allowCredentials: true
      },
      routes: {
        'ANY /quiz': {
          authorizationType: sst.ApiAuthorizationType.NONE,
          function: "lambda.handler",
        },
        'ANY /{proxy+}': "lambda.handler"
      },
    });
And the Axios call the /quiz/<id> route goes through the authorizer
Copy code
const headers = {
  Authorization: "Bearer 123",
  "Access-Control-Allow-Origin": "*",
  "Content-Type": "application/json",
};

export const getQuiz = async (id) => {
  try {
    const resp = await axios.get(
      `${process.env.REACT_APP_API_URL}/quiz/${id}`,
      { headers }
    );
    return resp.data;
  } catch (err) {
    console.log(err);
    return { error: err.message || "Unknown Error getting Quiz" };
  }
};
Also a few thoughts about the guide for adding an authorizer on the Api construct for https://docs.serverless-stack.com/constructs/Api#adding-auth. The code for adding a custom authorizer does not work. It displays
Copy code
import { HttpLambdaAuthorizer } from "@aws-cdk/aws-apigatewayv2-authorizers";
import { Function, Api } from "@serverless-stack/resources";

const authorizer = new Function(this, "AuthorizerFn", {
  handler: "src/authorizer.main",
});
But the actual lambda authorizer code needs a configuration object like
Copy code
const authorizer = new HttpLambdaAuthorizer({  
      authorizerName: "QuizAuthorizer",
      responseTypes: [HttpLambdaResponseType.IAM],
      handler: new sst.Function(this, "Authorizer", {
        handler: "src/authorizer.main",
      }),
      resultsCacheTtl: Duration.seconds(0)
    });
The authorizer also takes in a resultsCacheTtl that defaults to 300 seconds I believe and this threw me off. When I first tried my authentication Lambda the handler failed but then that result was cached and It took me awhile to realize thats why it wasn't calling the lambda.
f

Frank

01/26/2022, 12:44 AM
Hey @Dan Russell, sorry for the late follow up. We were in the middle of updating CDK to v2, and some of the code snippet might be inconsistent, sorry about the confusion.
Good point on
resultsCacheTtl
, we should probably mention that in the doc more clearly.
Btw, did you get the cors issue figured out in the end?
d

Dan Russell

01/28/2022, 3:46 PM
@Frank Hey thanks for the response. I had to open OPTIONS ("OPTIONS /{proxy+}") routes and return a 200 with access control headers. I had seen some examples of setting up API gateway to do this but I had it working already so I am not sure if there may be a better way.
f

Frank

01/30/2022, 8:53 PM
Ah gotcha. Manually handling the OPTIONS route.
Glad u figured it out 👍
2 Views