Reputation: 107
Despite looking for hours I cannot find a solution to my simple cors error. I am getting the following the in the browser:
Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3001%2Fapi%2Fauth%2Fauth%2Fgoogle%2Fcallback&scope=profile%20email&client_id=******.apps.googleusercontent.com' (redirected from 'http://localhost:3000/api/auth/auth/google') from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I just replaced the client ID for security reasons for this post. When I make this call in Postman/Thunder Client it gives back a 200 response and seems to work fine
So I have tried using cors NPM package in express app.use(cors());
also tried using this function in server.js app.all("/*", function (req, res, next) { res.header("Access-Control-Allow-Origin", "*"); next(); });
I've also tried using `
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(proxy("/api/auth/auth/google", {
target: "https://localhost:3000/",
changeOrigin: true
}));
}
I've just about done every solution in the book I found on SO, and none have seemed to work thus far. Any help would be so appreciated Here is my code:
Package.json in client
{
"name": "tasktracker",
"proxy": "http://localhost:3001/",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.13.0",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
"axios": "^0.21.1",
"http-proxy-middleware": "^2.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"web-vitals": "^1.1.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Homepage.js
import React from "react";
import API from "../components/utils/API";
export default function HomePage() {
const handleLogin = () => {
API.login();
};
const testing = () => {
console.log("Hello world!");
API.testing();
};
return (
<div>
<h1>Let's login with Google</h1>
<button onClick={handleLogin}>Login</button>
<button onClick={testing}>Testing</button>
</div>
);
}
API.js
import axios from "axios";
export default {
login: function () {
return axios.get("/api/auth/auth/google");
},
testing: function () {
return axios.get("/api/auth/test");
},
};
Server.js
const express = require("express");
const passport = require("passport");
const routes = require("./routes");
const app = express();
const PORT = process.env.PORT || 3001;
const cors = require("cors");
app.use(cors());
// Define middleware here
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
require("./config/passport");
app.use(passport.initialize());
// Add routes, both API and view
app.use(routes);
// Start the API server
app.listen(PORT, function () {
console.log(`🌎 ==> API Server now listening on PORT ${PORT}!`);
});
auth.js (auth routes)
const router = require("express").Router();
const passport = require("passport");
const cors = require("cors");
const CLIENT_HOME_PAGE_URL = "http://localhost:3000";
/Route is api/auth/test
router.get("/test", function (req, res) {
res.send(console.log("Test to backend"));
});
//Route is api/auth/auth/google/callback
router.get(
"/auth/google/callback",
passport.authenticate("google", {
successRedirect: CLIENT_HOME_PAGE_URL,
failureRedirect: "/",
session: false,
}),
function (req, res) {
var token = req.user.token;
res.redirect("http://localhost:3000?token=" + token);
}
);
//Route is api/auth/auth/google/
router.get(
"/auth/google",
passport.authenticate("google", { scope: ["profile", "email"] })
);
module.exports = router;
Passport.js
var passport = require("passport");
var GoogleStrategy = require("passport-google-oauth").OAuth2Strategy;
passport.serializeUser(function (user, done) {
done(null, user);
});
passport.deserializeUser(function (user, done) {
done(null, user);
});
passport.use(
new GoogleStrategy(
{
clientID:
"*****",
clientSecret: "*****",
callbackURL: "http://localhost:3001/api/auth/auth/google/callback",
},
function (accessToken, refreshToken, profile, done) {
var userData = {
email: profile.emails[0].value,
name: profile.displayName,
token: accessToken,
};
done(null, userData);
}
)
);
I know it's a bit of a long post, if anyone has any ideas or solutions would greatly help me a lot.
Upvotes: 2
Views: 1925
Reputation: 345
I was facing the same problem recently. Using
window.location.href = "http://localhost:5000/api/auth/google"
instead of
axios.get("/api/auth/auth/google")
solved the problem.
On successful authentication, if you want to redirect the user to the original url on which the user made the login request, you can do this...
const currentUrl = window.location.href
const encodedParam = encodeURI(`?redirectUrl=${currentUrl}`)
window.location.href = `http://localhost:5000/api/auth/google${encodedParam}`
Store the redirect value in a session
req.session.redirectPath = req.query.redirectUrl
and after authentication, use this in your callback route
Upvotes: 6