req.session.user 如果注销或测试是否已验证则未定义

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

我正在将 Express 和节点用于 React 应用程序,但谷歌身份验证不起作用。我正在使用快速会话。当我登录到我的 React 应用程序时,它可以识别 req.session.user,但是当我注销或使用路由获取用户时,它说 req.session.user 未定义

这就是我的 app.js 的样子:

import express from "express";
import api from "./routes/api.js";
import path from "path";
import { OAuth2Client } from 'google-auth-library';
import dotenv from 'dotenv';
import session from 'express-session';
dotenv.config();

const client = new OAuth2Client(process.env.REACT_APP_GOOGLE_CLIENT_ID);
const users = new Array();

let app = express();
let sessionHandler = session({
   //used to sign the session id, maxAge is the time in ms
   secret: process.env.SECRET,
   name: 'id',
   saveUninitialized: false,
   resave: false,
   cookie: {
   maxAge: null,
   secure: true,
   httpOnly: true,
   sameSite: 'strict'
   }
});

app.use(express.static("client/build"))

app.use(express.json());

app.use("/api", api);

function sessionMiddleWare (req, res, next) {sessionHandler(req, res, next);}

app.post("/auth", sessionMiddleWare, async (req, res) =\> {
   //TODO: should validate that the token was sent first
   const { token } = req.body;
   const ticket = await client.verifyIdToken({
       idToken: token,
       audience: process.env.REACT_APP_GOOGLE_CLIENT_ID
       });
   if (!ticket) {
       return res.sendStatus(401);
   }
   const { name, email, picture } = ticket.getPayload();
   //TODO: may want to update and insert the user's name, email and picture in the db.
   //For now I will be using an array, as a mock data that is on top of the app.js
   const user = { "name": name, "email": email, "picture": picture };
   const existsAlready = users.findIndex(elem =\> elem.email === email);

   if (existsAlready \< 0) {
      //insert
      users.push(user);
   } else {
     //update
     users\[existsAlready\] = user;
   }
   //TODO: create a session cookie send it back to the client
   req.session.regenerate(function (err) {
   if (err) {
   //server error, couldn't create the session
   return res.sendStatus(500);
   }
   //store the user's info in the session
   req.session.user = user;
   res.json({ user: user });
   });
});

function isAuthenticated(req, res, next) {
   console.log(req.session.user);
   if (!req.session.user) {
   //unauthorized
   return res.sendStatus(401);
  }
  next();
}

app.get("/protected", sessionMiddleWare, isAuthenticated, function (req, res) {
  //would actually be doing something
  res.sendStatus(200);
});

app.get("/logout", sessionMiddleWare, isAuthenticated, function (req, res) {
    //destroy the session
    req.session.destroy(function (err) {
   //callback invoked after destroy returns
   if (err) {
     //server error, couldn't destroy the session
     return res.sendStatus(500);
   }
  res.clearCookie('id');
  res.sendStatus(200);
  });
});

export default app;

这是前端的 App.js:

import './App.css';
import Header from "./components/Header.js";
import { useState } from 'react';
import { GoogleLogin, GoogleOAuthProvider } from '@react-oauth/google';

function App() {
  const [username, setUserName] = useState("");

  //handle the login
  const handleLogin = async googleData =>{
    const res = await fetch("/auth", {
      method: "POST",
      body: JSON.stringify({token: googleData.credential}),
      headers: {
        "Content-Type": "application/json"
      }
    });
    // server will be replying with the info
    const data = await res.json();
    console.log(data);
    setUserName(data.user.name);
  }

  //handle log out, nothing to do with google, only has to do with the
  //session on the Express server
  const handleLogout = async () => {
    await fetch("/logout");
    setUserName("");
  }

  //protected route callback
  const protectedRoute = async () => {
    const resp = await fetch("/protected");
    if(resp.status === 200) {
      // eslint-disable-next-line no-alert
      alert("You are authorized to see this");
    } else if (resp.status === 401) {
      // eslint-disable-next-line no-alert
      alert("You are not authorized to see this!");
    } else {
      // eslint-disable-next-line no-alert
      alert("Something went wrong!");
 }
 }
return (
<div className="App">
  <h2>Welcome {username ? username : "Anonymous"}</h2>
  <Header/>
  <GoogleOAuthProvider clientId={process.env.REACT_APP_GOOGLE_CLIENT_ID}>
    {!username && 
    <GoogleLogin
      onSuccess={handleLogin}
      onError={() =>{
        console.log('Loging Failed');
      }}
    /> }
    {username && <button onClick={handleLogout}>Logout</button>}
    <button onClick={protectedRoute}>Test protected</button>
  </GoogleOAuthProvider>
</div>
 );
}

export default App;
node.js mongodb express-session connect-mongo
© www.soinside.com 2019 - 2024. All rights reserved.