1

我正在构建一个简单的应用程序,其中 React 作为前端,Node/Express/MongoDB 作为后端。我正在使用 Passport 对用户进行身份验证。本地身份验证以及 Google 身份验证都在工作。

我似乎无法通过应用程序加载谷歌登录页面。我收到 CORS 错误。我在下面分享了错误。

在反应登录页面上:


const onClick = async () => {
    await Axios.get('/auth/google');
  };

代理中间件:

const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
  app.use(createProxyMiddleware('/auth', { target: 'http://localhost:4000' }));
};

节点服务器.js: app.use('/auth', require('./routes/auth'));

路由/身份验证文件:

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);
});

护照配置.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);
              });
          }
        });
      },
    ),
  );

错误:

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.

如果我单击上面的 XMLHttpRequest 链接,我就可以进行身份​​验证,并在我的数据库上使用 googleID 创建一个帐户。

我尝试了整个互联网上建议的不同选项,但没有一个对我有用。我不确定这里出了什么问题。

4

2 回答 2

0

根据文档,在声明任何路由器之前,尝试完全删除并在您的快速中间件中corsOptions使用该功能。cors()像这样:

app.use(cors());

让我知道这个是否奏效。

于 2020-08-20T17:27:57.987 回答
0
// 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) )
},[])

说明....
步骤 1 将在您的浏览器上加载您的服务器身份验证 url 并发出身份验证请求。
第 2 步然后在身份验证完成后在浏览器上重新加载客户端 url。
第 3 步使 api 端点可用于收集用户信息以更新反应状态
第 4 步调用端点,获取数据并更新用户状态。

于 2021-10-03T20:42:16.327 回答