3

I'm sending fetch from React to Express to authenticate with Google but I've been getting access blocked by CORS error. I'm redirecting the POST request from React to the Google URL for authentication. I tried using cors in the express app but I'm still getting the same error. For fetching

const handleClick = (e) => {
    fetch('http://localhost:8000/api/mail/login', {
        method: 'POST'
    })
    .then(res => res.text())
}

Using cors in express app.js

app.use(cors())

Trying to redirect to google auth

const oauth2Client = new google.auth.OAuth2(
    process.env.CLIENT_ID,
    process.env.CLIENT_SECRET,
    process.env.REDIRECT_URI
)

const url = oauth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: process.env.SCOPE
})

const gmail = google.gmail({
    version: 'v1',
    auth: oauth2Client
})

router.post('/login', (req, res, next) => {
    res.redirect(url)
})

The error: Access to fetch at 'https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=https%3A%2F%2Fmail.google.com%2F&response_type=code&client_id=727520060136-ngpfd4ll798v42gfclh7cms9ndqstt32.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8000' (redirected from 'http://localhost:8000/api/mail/login') from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
leowrites
  • 43
  • 2
  • 5
  • Seems pretty similar to this question, have you tried to implement their solution: https://stackoverflow.com/questions/48925165/cors-issue-with-google-oauth2-for-server-side-webapps ? – Alan Kersaudy May 25 '22 at 19:31
  • 1
    Authorization worked with Express by itself using the google api library and redirects to the authorization page. I'm not sure why it breaks when I send the fetch from React to Express, and Express to Google – leowrites May 25 '22 at 20:15
  • Honestly I don't know, I suggest you add more tags relating to the library you're trying to use, to make it easier for specialists of this google product to find your question. – Alan Kersaudy May 25 '22 at 22:14

1 Answers1

6

The authentication flow must happen in a visible browsing context, not with a fetch request. In other words: You must navigate the current tab to (or open a new tab at) http://localhost:8000/api/mail/login, the tab will then be redirected to https://accounts.google.com/o/oauth2/v2/auth?... and this page becomes visible. Now the user must interact with that page to choose/confirm their Google account, after which they will be redirected to a page on your server with an authorization code in the URL (for example, http://localhost:8000/callback?code=...) and your server must exchange the authorization code for an access token with a server-to-server call.

When made like this, none of the requests made is cross-origin, so no CORS will be involved at all.

Instead of the handleClick function, you need a login form like

<form action="http://localhost:8000/api/mail/login" method="post">
  <input type="submit" value="Press to log in"/>
</form>
Heiko Theißen
  • 12,807
  • 2
  • 7
  • 31
  • I have a similar to problem to the original poster, but I need to send authentication tokens in the header, and as far as I can tell, there is no way to do so with a form+action+method. What's the right workaround? – Rylan Schaeffer Jun 17 '22 at 18:22
  • 1
    That does not seem similar, then, but merits a separate question. – Heiko Theißen Jun 17 '22 at 18:57
  • It's identical to the OP except for adding `headers` to the `fetch()`. Your solution replaces the fetch, which doesn't work for including headers. – Rylan Schaeffer Jun 17 '22 at 18:59
  • 1
    You cannot navigate with an authentication header, so this makes a big difference. – Heiko Theißen Jun 17 '22 at 19:24
  • Maybe I should ask a different question: can you direct me towards a good resource that explains how a fetch is different from a form action? – Rylan Schaeffer Jun 17 '22 at 19:32
  • 1
    Form actions lead to [navigation requests](https://fetch.spec.whatwg.org/#navigation-request), which happen in a [browsing context](https://html.spec.whatwg.org/multipage/browsers.html#windows). – Heiko Theißen Jun 18 '22 at 07:05