SO Community,
I am working on using Passport's Google-OAuth2 strategy with a React front-end. Currently, I am able to get to the Google Login page front the back-end API call via Postman. However, if I make the call from the front-end using React, React treats the request as an unknown path and throws up our local 404 page.
Here is my code, presently (I've tried several different things to resolve the issue):
React Component
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>
)
}
}
I have two different buttons for testing purposes:
- The
<a>
"button" will redirect to our React 404 page. - The button which called the
handleGoogleLogin
function will hang. The "Network" tab in Google's DevTools shows a "pending" message from Google.
API Route
// 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);
});
}
));
};
Please let me know if I can provide any additional information.
Many thanks!