0
votes

I'm setting up stripe connect button in my React Component using Axios. I keep getting this error after redirection

Access to XMLHttpRequest at 'https://connect.stripe.com/oauth/token' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
Thankyou.js:40 Error: Network Error
    at createError (createError.js:16)
    at XMLHttpRequest.handleError (xhr.js:87)

I get the code from the url and create a curl request using axios.Post. This is the code in my redirect URL

// Thankyou.js
export default class Thankyou extends Component {
  constructor(props) {
    super(props);
  }
  componentDidMount() {
    const code = qs.parse(this.props.location.search, {
      ignoreQueryPrefix: true
    }).code;

    const params = {
      client_id: "*******************",
      client_secret: "**********************",
      grant_type: "authorization_code",
      code: code
    };

    axios
      .post(
        "https://connect.stripe.com/oauth/token",
        // apiBaseUrl,
        { params }
      )
      .then(function(response) {
        console.log(response);
      })
      .catch(function(error) {
        console.log(error);
      });
    console.log(code);
  }

  render() {
    return (
      <div>
        <h2>Thank you for connecting with us!</h2>
      </div>
    );
  }
}
6
API is not CORS enabled so you aren't exposing credentials in browser for all too see. Use a proxy and stripe server side sdk - charlietfl

6 Answers

1
votes

It's probably because Stripe doesn't provide JavaScript client so you either have to use your own server proxy or use something like "https://cors-anywhere.herokuapp.com/https://connect.stripe.com/oauth/token"

1
votes

There is nothing wrong with your code, but most likely the API endpoint the code trying to reach is not setup for JavaScript web app. CORS policy is set on the server-side and enforced primarily on the browser-side.

The best way to work around is to use Stripe's JavaScript solution such as Strip React Elements or Stripe.js.

A hacky way to get around CORS would be setting up Reverse proxy with solutions such as NGINX. For example, you can use the following nginx configuration:

server {
    listen 8080;
    server_name _;

    location / {
        proxy_pass http://your-web-app:2020/;
    }

    location /stripe/ {
        proxy_pass https://connect.stripe.com/;
    }
}

By doing so, all the API calls to Stripe.com could be through /stripe under your web app's URL. For example, calling http://yourapp/stripe/oauth/token would be same as calling https://connect.stripe.com/oauth/token

That being said, the second solution is hacky and Stripe may decide to block your reverse proxy server.

0
votes

basically you need to talk to whoever is hosting this https://connect.stripe.com/oauth/token to enable CORS (Cross Origin Resource Sharing )

It is a security measure implemented by most standard browsers to stop unwanted requests to your backend

0
votes

I would suggest reading through this site: https://stripe.com/docs/recipes/elements-react It gives specific instructions straight from stripe on using their API with react. Good luck!

0
votes

Learn about CORS

Think about it, there is anything wrong with your axios.post request, it's successfully contacting the server. But there is one more thing to do before the server let you execute or manipulate it's files.

For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and the Fetch API follow the same-origin policy.

So your cross-origin request and the server Cross-Origin Resource Sharing (CORS) have to match.

How do you solve it?

Depending on your server and the server side programming language your are implementing, you can configure the different parameters to handle your CORS.

For example, you can configure that the only allowed methods will be: GET HEAD

So if someone try to axios.post to your server with a different method like POST, it will return an error like this:

Access to XMLHttpRequest at 'https://connect.stripe.com/oauth/token' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
Thankyou.js:40 Error: Network Error
    at createError (createError.js:16)
    at XMLHttpRequest.handleError (xhr.js:87)

Resources:

https://www.w3.org/TR/cors/

https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

0
votes

I hope this answer would be useful to new users: This issue can be easily fixed by using an annotation in your spring boot rest controller class. Something like below (also ref screenshot): @CrossOrigin(origins = "http://localhost:4200")

Explicitly mention the react JS server URL that is causing this issue. Now after adding above annotation (with your react JS server URL) the browser will allow the flow.

All the best.

Rest Controller class