Ben Jonson
Ben Jonson

Reputation: 739

Cors Errors AWS Amplify Serverless Function Rest API Gateway

Access to XMLHttpRequest at 'https://***.execute-api.us-east-1.amazonaws.com/dev/users' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

I get the above error for the following code.

const user = await Auth.currentAuthenticatedUser();
    const token = user.signInUserSession.idToken.jwtToken;
    const header = {
        headers: {
            Authorization: token,
        },
    };
    const resp = await API.get("OneRestApi", "/users", header);

    

But from the postman calling the endpoint https://***.execute-api.us-east-1.amazonaws.com/dev/users results in no error. Postman output:

{
"success": "get call succeed!",
"url": "/users"

}

But when I change to another endpoint "/campaigns"

   const user = await Auth.currentAuthenticatedUser();
    const token = user.signInUserSession.idToken.jwtToken;
    const header = {
        headers: {
            Authorization: token,
        },
    };
    const resp = await API.get("OneRestApi", "/campaigns", header);

The code runs successfully. From APIGateWay I have enabled the cors. Here is the lambda code for the "/users" path.

/*
Copyright 2017 - 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at
    http://aws.amazon.com/apache2.0/
or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
*/

var express = require("express");
var bodyParser = require("body-parser");
var awsServerlessExpressMiddleware = require("aws-serverless-express/middleware");

// declare a new express app
var app = express();
app.use(bodyParser.json());
app.use(awsServerlessExpressMiddleware.eventContext());

// Enable CORS for all methods
app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "*");
    next();
});

/**********************
 * Example get method *
 **********************/

app.get("/users", function (req, res) {
    // Add your code here
    res.json({ success: "get call succeed!", url: req.url });
});

app.get("/users/*", function (req, res) {
    // Add your code here
    res.json({ success: "get call succeed!", url: req.url });
});

/****************************
 * Example post method *
 ****************************/

app.post("/users", function (req, res) {
    // Add your code here
    res.json({ success: "post call succeed!", url: req.url, body: req.body });
});

app.post("/users/*", function (req, res) {
    // Add your code here
    res.json({ success: "post call succeed!", url: req.url, body: req.body });
});

/****************************
 * Example put method *
 ****************************/

app.put("/users", function (req, res) {
    // Add your code here
    res.json({ success: "put call succeed!", url: req.url, body: req.body });
});

app.put("/users/*", function (req, res) {
    // Add your code here
    res.json({ success: "put call succeed!", url: req.url, body: req.body });
});

/****************************
 * Example delete method *
 ****************************/

app.delete("/users", function (req, res) {
    // Add your code here
    res.json({ success: "delete call succeed!", url: req.url });
});

app.delete("/users/*", function (req, res) {
    // Add your code here
    res.json({ success: "delete call succeed!", url: req.url });
});

app.listen(3000, function () {
    console.log("App started");
});

// Export the app object. When executing the application local this does nothing. However,
// to port it to AWS Lambda we will create a wrapper around that will load the app from
// this file
module.exports = app;

Interestingly the code worked before I added anoter path to the API.

Upvotes: 0

Views: 2607

Answers (1)

eli6
eli6

Reputation: 1034

Your have a problem with your preflight request. A preflight request ist only sent by browsers and not by tools like Postman, so that is why the Postman request is still working.

The preflight request is an OPTIONS request, so please check that you have an OPTIONS method in API Gateway for the path your are requesting, and check its configuration and that you for example aren't sending or expecting credentials with the OPTIONS request. Including credentials in a preflight request ist not allowed according to the Mozilla CORS Documentation.

A reason why the request stops working after adding another path might be that you have made manual changes (perhaps regarding Authentication or CORS) to your API in the API Gateway Console. When you then push the same API with Amplify those changes are often overwitten. Please check that this isn't the case. And try to make all changes through the Amplify API (if you have created the API there) to avoid those problems.

Upvotes: 3

Related Questions