I am having trouble utilizing Passport.js with React for Facebook login.
I was able to set up everything from the server with Express and Node.js to the client-side using React.js. From the client-side, I created a login button component that opens a new window which then hits my server and signs me into Facebook within the second window. Now the problem is how do I properly route the information back to the original window and update my state?
Here is my React code:
import React, { useState } from "react";
function Facebook() {
const [state, setState] = useState({
isAuth: false,
user: "",
token: "",
});
let content = !state.isAuth ? (
<>
<div>
<a href="http://localhost:4000/facebook">
<button
style={{
display: "inline-block",
fontSize: "14px",
padding: "13px 30px 15px 44px",
background: "#3A5A97",
color: "#fff",
textShadow: "0 -1px 0 rgba(0,0,20,.4)",
textDecoration: "none",
lineHeight: "1",
position: "relative",
borderRadius: "5px",
}}
>
Login with Facebook
</button>
</a>
</div>
</>
) : (
<>
<div>
<button onClick={handleLogout}>logout</button>
</div>
</>
);
return <>{content}</>;
}
export default Facebook;
Here is my Express server (I took out a lot of things that are unnecessary for your view):
const express = require("express");
const app = express();
const port = 4000;
const passport = require("passport");
const Strategy = require("passport-facebook").Strategy;
const cors = require("cors");
const jwt = require("jsonwebtoken");
passport.use(
new Strategy(
{
clientID: "<CLIENT_APP_ID>",
clientSecret: "<CLIENT_SECRET>",
// callbackURL: "http://localhost:3000/auth/facebook/callback",
callbackURL: "/auth/facebook/callback",
profileFields: ["id", "displayName", "email", "name"],
enableProof: true,
},
function (accessToken, refreshToken, profile, cb) {
// save the profile on the Database
// Save the accessToken and refreshToken if you need to call facebook apis later on
console.log(accessToken, "<-------------what is access token");
console.log(profile, "<--------------------what is the profile?");
cb(null, profile);
}
)
);
passport.serializeUser(function (user, cb) {
console.log("<--------should be serialized first");
cb(null, user);
});
passport.deserializeUser(function (obj, cb) {
console.log("<--------should be deserialized second");
cb(null, obj);
});
app.use(passport.initialize());
app.use(passport.session());
app.get("/facebook", passport.authenticate("facebook"));
app.get(
"/auth/facebook/callback",
passport.authenticate("facebook", {
session: false,
failureRedirect: "http://localhost:3000/error",
successRedirect: "http://localhost:3000/success",
}),
(req, res) => {
res.json();
}
);
app.listen(port, () => {
console.log(`App is listening on ${port}`);
});
I was having the same problem but implementing passport-steam strategy. I found this post about how to set up the Twitter OAUth with passport and react, and since the workflow was the same I was able to adapt it for my needs. Hope it help you too.