React: AWS Cognito token endpoint returns 400 invalid_grant when being redirected by a Shopify store

Viewed 1808

Our React app uses AWS Amplify and Cognito hosted UI for authentication. There is a feature in our app to link a Shopify store. To do that, we get the user's Shopify store URL and redirect the user to its admin panel to obtain permissions and access token. After the user grants permission, he is redirected again to our app.

The problem occurs at this point. When looking at the console, we see something like this. Cognito token endpoint throws 400 invalid_grant error. This error goes away when we refresh the page, but we think there should be a better solution.

Can someone please provide us with advice on how to overcome these Cognito errors? All helpful advice is highly appreciated.

enter image description here

The page that the user is redirected from the Shopify store is as follows.

import React, { useEffect } from "react";
import { Auth } from "aws-amplify";
import { useSelector, useDispatch } from "react-redux";
import * as api from "../../services/api";

const ShopifyAuthCallback = ({ history }) => {
  const classes = useStyles();
  const dispatch = useDispatch();
  const organizationId = useSelector(
    (state) => state.dashboard.userOrganizationId
  );

  useEffect(() => {
    Auth.currentSession()
      .then((res) => {
        const params = new URLSearchParams(window.location.search);
        const shopOrigin = params.get("shop");
        const authCode = params.get("code");

        api
          .post(`shopify/access-token`, {
            authCode: authCode,
            shopOrigin: shopOrigin,
            organizationId: organizationId,
          })
          .then((data) => {
            history.push("/");
          })
          .catch((error) => {
            console.error(error);
          });
      })
      .catch((error) => {
        console.log(error);
      });
  });

  return (
    <div>
      <p>Redirecting...</p>
    </div>
  );
};

export default ShopifyAuthCallback;

Amplify auth is set up in App.js as follows.

import React, { useEffect, useState } from "react";
import { createBrowserHistory } from "history";
import theme from "./theme";
import Routes from "./Routes";
import { withAuthenticator } from "aws-amplify-react";
import Amplify, { Auth } from "aws-amplify";
import aws_exports from "./aws-exports";
import { Router } from 'react-router-dom';
import {useSelector } from "react-redux";
import { useDispatch } from "react-redux";
import * as api from "services/api";

Amplify.configure(aws_exports);
Auth.configure();
const browserHistory = createBrowserHistory();

const App = () => {
  const dispatch = useDispatch();

  useEffect(() => {
    try {
      Auth.currentSession()
        .then(cognitoUser => {
          const { idToken: { payload } } = cognitoUser
          if (payload['custom:organization']) {
            // do something          }
          else {
            // do something else
          }
        })
        .then( async (res) => {
          // do something
        })
        .catch(err => {
          console.log(err);
        });
    } catch (e) {
      console.log(e);
    }
  }, []);

  return (
    <ThemeProvider theme={theme}>
      <Router history={browserHistory}>
        <Routes />
      </Router>
    </ThemeProvider>
  );
}

const signUpConfig = {
  header: "Create a new account",
  hideAllDefaults: true,
  defaultCountryCode: "1",
  signUpFields: [
    {
      label: "Name",
      key: "name",
      required: true,
      displayOrder: 1,
      type: "string"
    },
    {
      label: "Password",
      key: "password",
      required: true,
      displayOrder: 2,
      type: "password"
    },
    {
      label: "Email",
      key: "username",
      required: true,
      displayOrder: 4,
      type: "string"
    }
  ]
};

export default withAuthenticator(App, {
  signUpConfig
});

EDIT:

These are the request and response details of the Cognito token endpoint.

General:

Request URL: https://ogmo-dev.auth.eu-central-1.amazoncognito.com/oauth2/token
Request Method: POST
Status Code: 400 
Remote Address: 35.156.210.187:443
Referrer Policy: strict-origin-when-cross-origin

Response:

access-control-allow-credentials: true
access-control-allow-origin: https://dev.ogmo.xyz/
cache-control: no-cache, no-store, max-age=0, must-revalidate
content-type: application/json;charset=UTF-8
date: Sun, 25 Oct 2020 06:52:21 GMT
expires: 0
pragma: no-cache
server: Server
set-cookie: XSRF-TOKEN=<token_value>; Path=/; Secure; HttpOnly; SameSite=Lax
status: 400
strict-transport-security: max-age=31536000 ; includeSubDomains
vary: Origin
x-amz-cognito-request-id: b4cd564e-b0b1-42bf-a7a1-9361ce4db34d
x-application-context: application:prod:8443
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 1; mode=block

Request headers:

:authority: ogmo-dev.auth.eu-central-1.amazoncognito.com
:method: POST
:path: /oauth2/token
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
content-length: 147
content-type: application/x-www-form-urlencoded
origin: https://dev.ogmo.xyz
referer: https://dev.ogmo.xyz/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36

Form data:

grant_type: authorization_code
code: 91a86bdadbe488ae1cd5ec10343a3461
client_id: <client_id>
redirect_uri: https://dev.ogmo.xyz/
0 Answers
Related