[英]Facing CORS error even after adding CORS options on React/Node/Passport for Google Authentication
I am building a simple app with React as frontend and Node/Express/MongoDB as backend.我正在构建一个简单的应用程序,以 React 作为前端,以 Node/Express/MongoDB 作为后端。 I am authenticating user using Passport.
我正在使用 Passport 对用户进行身份验证。 Local authentication is working, as well as Google authentication.
本地身份验证和 Google 身份验证都在工作。
I just seem to not able to load the google login page through the app.我似乎无法通过应用程序加载谷歌登录页面。 I am getting CORS error.
我收到 CORS 错误。 I have shared the error below.
我在下面分享了错误。
On React Login page:在 React 登录页面上:
const onClick = async () => {
await Axios.get('/auth/google');
};
Proxy Middleware:代理中间件:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(createProxyMiddleware('/auth', { target: 'http://localhost:4000' }));
};
Node Server.js: app.use('/auth', require('./routes/auth'));
Node Server.js:
app.use('/auth', require('./routes/auth'));
routes/auth file:路线/授权文件:
const cors = require('cors');
var corsOptions = {
origin: 'http://localhost:3000',
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
preflightContinue: false,
optionsSuccessStatus: 204,
};
router.get(
'/google',
cors(corsOptions),
passport.authenticate('google', {
scope: ['profile', 'email'],
}),
);
router.get('/google/redirect',cors(corsOptions), passport.authenticate('google'), (req, res) => {
res.send(req.user);
});
passportconfig.js:护照配置.js:
passport.use(
new GoogleStrategy(
{
clientID: ClientID,
clientSecret: ClientSecret,
callbackURL: '/auth/google/redirect',
proxy: true,
},
(accessToken, refreshToken, profile, done) => {
// passport callback function
//check if user already exists in our db with the given profile ID
User.findOne({ googleId: profile.id }).then((currentUser) => {
if (currentUser) {
//if we already have a record with the given profile ID
done(null, currentUser);
} else {
//if not, create a new user
new User({
googleId: profile.id,
})
.save()
.then((newUser) => {
done(null, newUser);
});
}
});
},
),
);
Error:错误:
Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fgoogle%2Fredirect&scope=profile%20email&client_id=<clientID>.apps.googleusercontent.com' (redirected from 'http://localhost:3000/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.
If I click on the above XMLHttpRequest link, I am able to authenticate and an account is created on my DB with googleID.如果我点击上面的 XMLHttpRequest 链接,我就可以进行身份验证,并使用 googleID 在我的数据库上创建一个帐户。
I have tried different options suggested throughout inte.net, but none of them is working for me.我尝试了整个 inte.net 中建议的不同选项,但没有一个适合我。 I am not sure what is going wrong here.
我不确定这里出了什么问题。
According to the documentation , try removing the corsOptions
entirely and just use the cors()
function in your express middle-ware before any router is declared.根据文档,尝试完全删除
corsOptions
并在声明任何路由器之前在您的快速中间件中使用cors()
function。 Like so:像这样:
app.use(cors());
Let me know if this works.让我知道这个是否奏效。
// step 1:
// onClick handler function of the button should use window.open instead
// of axios or fetch
const loginHandler = () => window.open("http://[server:port]/auth/google", "_self")
//step 2:
// on the server's redirect route add this successRedirect object with correct url.
// Remember! it's your clients root url!!!
router.get(
'/google/redirect',
passport.authenticate('google',{
successRedirect: "[your CLIENT root url/ example: http://localhost:3000]"
})
)
// step 3:
// create a new server route that will send back the user info when called after the authentication
// is completed. you can use a custom authenticate middleware to make sure that user has indeed
// been authenticated
router.get('/getUser',authenticated, (req, res)=> res.send(req.user))
// here is an example of a custom authenticate express middleware
const authenticated = (req,res,next)=>{
const customError = new Error('you are not logged in');
customError.statusCode = 401;
(!req.user) ? next(customError) : next()
}
// step 4:
// on your client's app.js component make the axios or fetch call to get the user from the
// route that you have just created. This bit could be done many different ways... your call.
const [user, setUser] = useState()
useEffect(() => {
axios.get('http://[server:port]/getUser',{withCredentials : true})
.then(response => response.data && setUser(response.data) )
},[])
Explanation....
解释....
step 1 will load your servers auth url on your browser and make the auth request.
第 1 步将在您的浏览器上加载您的服务器身份验证 url 并发出身份验证请求。
step 2 then reload the client url on the browser when the authentication is complete.
步骤2然后在身份验证完成后在浏览器上重新加载客户端url。
step 3 makes an api endpoint available to collect user info to update the react state
第 3 步使 api 端点可用于收集用户信息以更新反应 state
step 4 makes a call to the endpoint, fetches data and updates the users state.
第 4 步调用端点,获取数据并更新用户 state。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.