Reputation: 73
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.
Upvotes: 6
Views: 10151
Reputation: 16892
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>
Upvotes: 15