Passport Google OAuth2.0 - How can I pass an object as a response after a successful authentication?

Viewed 329

I need to get some info back after successful Google authentication to be consumed by React, allowing access to the private routes on the client-side like I do with my local strategy login (an {isAuthenticated: true} is sent to React, which uses this info to set the state of a custom hook that is read by a private route wrapper component to check if the user can access the app's main page; otherwise the user is sent back to login page).

However, since I need to redirect the user to http://localhost:5000/auth/google from the "Sign in with Google" React button and Google's auth route deals with the rest until it redirects the user to the app's main page, I can't see how I could get it to work by simply writing a res.json like I do with local strategy login (which, in my last attempt, resulted in the json being sent directly to the browser screen).

If it makes any difference: I'm using Passport JWT all over my server to protect routes from unauthenticated requests, so I also set session: false on Google and generated a JWT token before res.redirect. Below is my /auth route, where I handle Google access:

auth.js

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

const clientUrl =
  process.env.NODE_ENV === "production"
    ? process.env.CLIENT_URL_PROD
    : process.env.CLIENT_URL_DEV;

router.get(
  "/google/movie-log",
  passport.authenticate("google", {
    failureRedirect: clientUrl + "/login",
    session: false,
  }),
  (req, res) => {
    const token = req.user.generateJWT();

    res.cookie("access_token", token, { httpOnly: true, sameSite: true });

    res.redirect(clientUrl + "/diary");
  }
);

module.exports = router;

Login.js (This is the login component on React)

function Login() {
  const authContext = useContext(AuthContext);
  const navigate = useNavigate();
  const { state } = useLocation();
  const [message, setMessage] = useState(null);

  const [userInfo, setUserInfo] = useState({
    email: "",
    password: "",
  });

  function handleInfo(event) {
    const { name, value } = event.target;

    setUserInfo((prevValue) => {
      return {
        ...prevValue,
        [name]: value,
      };
    });
  }

  function handleLogin(event) {
    event.preventDefault();

    axios
      .post("/login", userInfo)
      .then((response) => {
        const { isAuthenticated, user, message } = response.data;

        if (isAuthenticated) {
          authContext.setUser(user);
          authContext.setIsAuthenticated(isAuthenticated);
          navigate(state?.path || "/diary");
        } else {
          setMessage(message);
        }
      })
      .catch((err) => {
        console.log(err);
      });
  }

  return (

      //login form - removed to clear the clutter

        <GoogleButton
          style={{ width: "100%" }}
          onClick={(event) => {
            event.preventDefault();
            window.open("http://localhost:5000/auth/google", "_self");
          }}
        />
  );
}

export default Login;

Any help will be very much appreciated.

0 Answers
Related