Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't solve CORS error. Already added response headers and cors: true. #5846

Closed
edlgg opened this issue Feb 19, 2019 · 9 comments
Closed

Can't solve CORS error. Already added response headers and cors: true. #5846

edlgg opened this issue Feb 19, 2019 · 9 comments

Comments

@edlgg
Copy link

edlgg commented Feb 19, 2019

Hello,
This question has probably been asked hundreds of times but I cant seem to make it work. I have a post serverless function but I keep getting a cors error not matter what I do. When I test it on post man it works correctly.

functions:
  authorizeUser:
    handler: authorizeUser.authorizeUser

 createReaction:
    handler: createReaction.createReaction
    events:
      - http:
          method: post
          path: reactions/createReaction
          cors: true
          authorizer: authorizeUser

function

module.exports.createReaction = async (event, context) => {
  context.callbackWaitsForEmptyEventLoop = false
  try {
    // Code
    return {
      statusCode: 200,
      headers: { // I ve added extra headers just to see if it helps
        'Access-Control-Allow-Origin' : '*', 
        'Access-Control-Allow-Methods':	'post',
        'Access-Control-Allow-Credentials' : true,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        // Code
      }),
    }
  } catch (err) {
    return errorHandler(err)
  }
}

Front end code

const response = await this.$axios.$post(
          'reactions/createReaction', // base url is automatically added
          {
            newReaction: {
              userId: "605e01f7-9b3f-440b-837d-981c27cc2998",
              entityId: "9ea84374-c17b-4bda-871d-7edf2ca0d207",
              entityType: "Article",
              reactionType: "Like"
            },
            headers: {
              Authorization: this.$store.state.auth.token
            }
        })

Custom Authorizer

module.exports.authorizeUser = async (event, context, callback) => {
  try {
    const token = event.authorizationToken
    const decoded = jwt.verify(token, process.env.JWT_SECRET)

    const user = decoded.user
    if (!user) {
      throw new Error('Invalid Token')
    }
    context['authorizedUserId'] = user.id
    const policyDocument = {
      principalId: user.id,
      policyDocument: {
        Version: '2012-10-17',
        Statement: [
          {
            Action: 'execute-api:Invoke',
            Effect: 'Allow',
            Resource: '*',
          },
        ],
      },
      context,
    }
    callback(null, policyDocument)
  } catch (err) {
    return errorHandler(err)
  }
}

Error
screen shot 2019-02-18 at 18 56 59

@delprofundo
Copy link

Hey,

I was in this exact spot last week. Do you use a custom authorizer?

I would recommend having a look at the CloudWatch logs for the APIG endpoint you are hitting.

I found about 2 weeks back that I was getting a cors issue when my custom authorizer was erroring out in a strange way. It appears there are some failures in the custom authorizer that aren't reflected in the logs for the custom authorizer but are in the general APIG logs.

Have a look at those and tell me what you see and I may be able to point you in the right direction.

@edlgg
Copy link
Author

edlgg commented Feb 19, 2019

Hello @delprofundo,
Thanks for the help. I'm in fact using a custom authorizer. I've updated the post with the authorizer's code. As for the cloudwatch logs, for some reason I dont see any logs when calling the function from my front-end code. When I use postman it works and I can see the logs in cloudwatch. I thought I was hitting the wrong end point but I dont think thats the case since im getting a 401 error not a 403.

@delprofundo
Copy link

delprofundo commented Feb 19, 2019

Hey,

Sorry I wasn't totally clear in two ways:

  1. The errors I was getting weren't actually in the auth function but were actually in the http handler that was being called after it. was really quite a strange edge case.
  2. When I say check the logs I mean the APIG logs NOT the Auth logs. The APIG logs are at the very bottom of your CW stack and they are listed by the APIG ID. You also need to turn on APIG logs to see them. This shows you how.

You will find the APIG logs will probably have some extra detail on your problem (and a tonne of cruft that won't help).

In other news your authorizer looks alright.

It occurred to me I recently changed how I declare my CORS settings....look here:

    events:
      - http:
          path: /
          method: post
          cors:
            origin: "*"
            headers:
              - X-Auth-Class
              - Authorization
          authorizer:
            name: authorize
            type: request
            resultTtlInSeconds: 0

I had intermittent problems with auth before I applied this that I still cannot explain. I can confirm I dont get them anymore as I've run every function in the application 1million times in the last week with no cors or auth issues.

(final thing I would recommend adding a check on an epoch time reference in the token payload)

@edlgg
Copy link
Author

edlgg commented Feb 19, 2019

I changed the yml settings to this

  createReaction:
    handler: createReaction.createReaction
    events:
      - http:
          method: post
          path: reactions/createReaction
          cors:
            origin: "*"
            headers:
              - X-Auth-Class
              - Authorization
          authorizer: 
            name: authorizeUserR
            type: request
            resultTtlInSeconds: 0

Now I get the following error
screen shot 2019-02-18 at 23 04 16

I dont see any usefull information in the cloudwatch APIG logs. I dont know if Im missing something.
screen shot 2019-02-18 at 23 05 57

Also, what do you mean by 'adding a check on an epoch time reference in the token payload' isnt a time validation done in the jwt.verify() method?

@delprofundo
Copy link

Hmmm ok this is now diverging from my issue a bit im afraid, I'll point out this that the list of headers there are mine, you may not be using those (almost certainly wont be using X-Auth-Class).

That said it looks like you are returning a content type header and it may be required in the set of headers there....from memory I THINK the event method settings are duplicated for the options call, so perhaps remove my headers and add the ones you are using.

Now I did notice there were some update issues with cloud formation when changing cors settings (some of my settings would jag for a few deploys till i finally removed everything and did a clean deploy and data migration) so maybe blow away the whole service and try again if you dont move further forward.

I'll keep thinking, let me know if anything changes.

@drexler
Copy link
Contributor

drexler commented Feb 19, 2019

@edlgg try adding this resource to your serverless.yml:

resources:
  Resources:
    GatewayResponseDefault4XX:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers'"
        ResponseType: DEFAULT_4XX
        RestApiId:
          Ref: 'ApiGatewayRestApi'

@edlgg
Copy link
Author

edlgg commented Feb 19, 2019

@drexler I added the resource and now I no longer get the cors error. However I still get a 401. When I check the APIG logs I see an 'UNAUTHORIZED' message. If I try to see the logs of the authorizer function there arent any logs.
screen shot 2019-02-19 at 12 19 23
screen shot 2019-02-19 at 12 19 57

@drexler
Copy link
Contributor

drexler commented Feb 19, 2019

@edlgg even with some console logs in there, it's not getting invoked? It should i reckon. There's probably an issue with the JWT being sent with the request or some other subtle error. Remember with an authorizer, last time i checked, you cant send back a custom error message.

Curious what does this log when added to the authorizer function:

...
catch (err) {
    console.error(`Error in Authorizer. Reason: ${JSON.stringify(err)}`)
    return errorHandler(err)
}

@pmuens
Copy link
Contributor

pmuens commented Jul 30, 2019

Closing this issue since it's quite stale. Please refer to the Serverless Forums or Gitter where issues like this can be discussed with our broad developer community.

@pmuens pmuens closed this as completed Jul 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants