SO社区,
我正在将 Passport 的 Google-OAuth2 策略与 React 前端一起使用。目前,我可以通过 Postman 访问后端 API 调用前面的 Google 登录页面。但是,如果我使用 React 从前端进行调用,React 会将请求视为未知路径并抛出我们的本地 404 页面。
这是我的代码,目前(我已经尝试了几种不同的方法来解决这个问题):
反应组件
import React, { Component } from 'react';
// MaterialUI Components
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
// React APIs
import API from "../utils/API";
const styles = {
button: {
marginTop: "1rem"
}
}
export default class LoginForm extends Component {
state = {
email: "",
password: ""
};
handleInputChange = event => {
const { name, value } = event.target;
this.setState({
[name]: value
});
};
handleSubmitForm = () => {
let newLogin = {
email : this.state.email,
password : this.state.password
}
API.login(newLogin).then(res => console.log(res)).catch(err => console.log(err));
};
handleGoogleLogin = () => {
fetch("/api/auth/google", {mode: 'no-cors'})
.then(response => {
console.log(response)
})
.catch(err => {
console.log(err);
});
}
render() {
return (
<div>
<form noValidate autoComplete="off">
<div>
<TextField
id="email"
label="Email"
name="email"
value={this.state.email}
onChange={this.handleInputChange}
margin="normal"
/>
</div>
<div>
<TextField
id="password"
label="Password"
type="password"
name="password"
onChange={this.handleInputChange}
margin="normal"
/>
</div>
<Button
onClick={this.handleSubmitForm}
style={styles.button}
variant="outlined"
size="small">Login</Button>
<Button
onClick={this.handleGoogleLogin}
style={styles.button}
variant="outlined"
size="small">Google Login</Button>
</form>
<div>
<a type="button" className="MuiButtonBase-root MuiButton-root MuiButton-outlined MuiButton-sizeSmall" href="/api/auth/google">Google A Tag</a>
</div>
</div>
)
}
}
我有两个不同的按钮用于测试目的:
- “
<a>
按钮”将重定向到我们的 React 404 页面。 - 调用该
handleGoogleLogin
函数的按钮将挂起。Google DevTools 中的“网络”选项卡显示来自 Google 的“待处理”消息。
API 路由
// Redirect to Google authentication.
app.get('/api/auth/google', function(){
console.log("google api")
}, passport.authenticate('google', { scope: ['profile', "email"] }));
// After authentication, redirect back to home page.
app.get('/api/auth/google/callback', passport.authenticate('google', { successRedirect: "/", failureRedirect: '/404', session: false }), function(req, res) {
// var token = req.user.token
// res.redirect('/');
res.redirect("http://localhost:3000?token=" + token);
// console.log("google callback")
});
Passport.js
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
const db = require('../models');
const keys = require('../config/keys');
const opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = keys.secretOrKey;
module.exports = (passport) => {
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
passport.use(
new JwtStrategy(opts, (jwtPayload, done) => {
db.Users
.findOne({
where: {
id: jwtPayload.id
}
})
.then((user) => {
if (user) {
return done(null, user);
}
return done(null, false);
})
.catch((err) => console.log(err));
})
);
passport.use(
new GoogleStrategy({
clientID: keys.googleClientID,
clientSecret: keys.googleClientSecret,
callbackURL: "http://localhost:3001/api/auth/google/callback"
},
function(accessToken, refreshToken, profile, done) {
db.Users.findOrCreate({ googleId: profile.id }, function (err, user) {
return done(err, user);
});
}
));
};
如果我可以提供任何其他信息,请告诉我。
非常感谢!