MERN OAuth实现不重定向到google登录页面。

问题描述 投票:0回答:1

我目前正在使用MERN堆栈运行一个webserver,我试图让OAuth登录正常工作。然而,当我点击 "用google登录 "按钮时,react加载了主页(但URL改变了)。直接获取URL会得到服务器的302响应,但我的前端并没有改变。

服务器.js

const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const logger = require('morgan');
const cors = require('cors');
const secure = require('express-force-https');
const passport = require('passport');
const cookieSession = require('cookie-session');

require('dotenv').config();

const app = express();
const port = process.env.PORT || 5000;
const dbRoute = process.env.MONGODB_URI || 'NO DB ROUTE PROVIDED';

// db setup
mongoose.connect(
  dbRoute,
  {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    dbName: process.env.DATABASE_NAME,
  }
);

let db = mongoose.connection;
db.once('open', () => console.log("Connected to the database"));
db.on('error', console.error.bind(console, "MongoDB connection error: "));

// middleware
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false })); // body parsing
app.use(bodyParser.json());
app.use(logger("dev"));
app.use(express.static(path.join(__dirname, "client", "build"))); // for serving up the clientside code
app.use(secure); // ensure that the connection is using https
app.use(cookieSession({ // cookies!
  maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
  keys:['vcxzkjvasddkvaosd'] // yeah i'm sure that's secure enough
}));

// models
require('./models/rule');
require('./models/affix');
require('./models/user');

// passport security
require('./config/passport');
app.use(passport.initialize());
app.use(passport.session());

// routes
app.use(require('./routes'));

// The "catchall" handler: for any request that doesn't
// match one above, send back React's index.html file.
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname+'/client/build/index.html'));
});

app.listen(port);

console.log(`Server listening on ${port}`);

路径(有几个索引文件在不同的文件夹中,所以这个路由的完整路径是 /api/user/google)

const mongoose = require('mongoose');
const passport = require('passport');
const router = require('express').Router();
const auth = require('../auth');
const User = mongoose.model('User');

router.get('/google', 
  passport.authenticate('google', {
    scope: ['profile', 'email']
  })
);

router.get('/google/callback', 
  passport.authenticate('google', { failureRedirect: '/affixes'}),
  (req, res) => {
    res.redirect('/?token=' + req.user.token);
  }
);

Passport.js

const mongoose = require('mongoose');
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
require('dotenv').config();

const User = mongoose.model('User');

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findById(id).then((user) => {
    done(null, user);
  })
});

passport.use(new GoogleStrategy({
    clientID: process.env.OAUTH_CLIENT_ID,
    clientSecret: process.env.OAUTH_CLIENT_SECRET,
    callbackURL: '/api/user/google/callback',
    proxy: true
  },

  (accessToken, refreshToken, profile, done) => {
    User.findOne({ googleId: profile.id })
      .then((existingUser) => {
        if (existingUser) {
          done(null, existingUser);
        } else {
          new User({ googleId: profile.id }).save()
            .then((user) => done(null, user));
        }
      });
  }
));

前台登录页面(有一个获取按钮和一个链接按钮。如上所述,行为不同)

import React from 'react';
import {
  ComingSoon
} from '../Common';
import {
  Button
} from '@material-ui/core';

const handleClick = () => {
  fetch('/api/user/google')
}

export default function Login() {
  return (
    <>
      <Button onClick={handleClick}>
        Login with Google
      </Button>

      <a href="/api/user/google"><button>Log in with Google</button></a>
    </>
  );
}

更新:看起来像是某种CORS问题,虽然我仍然不知道如何解决。浏览器会吐出

Access to fetch at '...' (redirected from 'http://localhost:3000/api/user/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 an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

添加所需的头,我得到了

Access to fetch at '...' (redirected from 'http://localhost:3000/api/user/google') from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
node.js reactjs express passport.js passport-google-oauth
1个回答
0
投票

事实证明,我对这个问题的性质是相当错误的! 问题是我的OAuth端点的获取请求调用了我的前端,而不是我的后端,因为请求中包含了以下内容。text/html 在其 Accept 头的问题。使用react高级代理设置来路由到正确的URI修复了这个问题。

请看 https:/github.comfacebookcreat-react-appissues5103)。https:/github.comfacebookcreat-react-appissues8550。

© www.soinside.com 2019 - 2024. All rights reserved.