2

我有一个 express-react-typescript-redux-passport 项目,我在其中使用createApiredux 工具包在后端调用/getuserapi。

我正在使用passport-google-oauth20策略对用户进行身份验证,并且用户已成功通过身份验证。

我的问题是没有调用passport jsdeserializeUser()函数(即使serializeUser()调用了,并且使用google策略对用户进行了身份验证),因此req.user前端向后端发送请求时不会自动设置该参数。

怀疑deserializeUser没有被调用,因为我没有在我的端点中设置 axio 的{ withCredentials: true }(或 fetch 的{credentials: "include"})参数。createApi如何在 RTK 的 createApi 中发送此参数?

如何指定凭据:包括此处?

这是我的 createApi 函数

export const userApiSlice = createApi({
  reducerPath: "api",
  baseQuery: fetchBaseQuery({
    baseUrl: "http://localhost:4000",
    prepareHeaders(headers) {
      return headers;
    },
  }),
  endpoints(builder) {
    // debugger;
    return {
      fetchUser: builder.query<IUser, number | void>({
        query: () => {
          debugger;
          return `/getuser`;
        },
      }),
    };
  },
});

这是我的服务器 index.js

import express from "express";
import mongoose from "mongoose";
import cors from "cors";
import session from "express-session";
import passport from "passport";

var GoogleStrategy = require("passport-google-oauth20").Strategy;
import { IGoogleAuthUser } from "./types/authTypes";
const PORT = process.env.PORT || 4000;

require("dotenv").config();

const app = express();

mongoose.connect(process.env.LOCAL_DB_ADDRESS, () => {
  console.log("connected to mongoose db");
});

app.use(express.json());
app.use(cors({ origin: "http://localhost:3000", credentials: true }));

app.use(
  session({
    secret: process.env.SESSION_SECRET,
    resave: true,
    saveUninitialized: true,
  })
);
app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser((user: IGoogleAuthUser, done: any) => {
  //send a cookie to browser to store user id in session
  const { id} = user;
  console.log("serializeUser called");
  return done(null, id);
});

// why isn't this called???
passport.deserializeUser((userId: string, done: any) => {
  //attaches the cookie id from session to req.user
  console.log("deserializeUser userId : ", userId);
  return done(null, userId);
});

//google strategy
passport.use(
  new GoogleStrategy(
    {
      clientID: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      callbackURL: "/auth/google/callback",
    },
    function (accessToken: any, refreshToken: any, profile: any, done: any) {
      //this is called on succesful authentication with the above Google Stratety     
      console.log("successful authorization");
      done(null, profile);
    }
  )
);

//when user clicks on 'login with google' /auth/google is hit
app.get(
  "/auth/google",
  passport.authenticate("google", { scope: ["profile", "email"] }),
  (req, res) => {
    console.log("/auth/google called"); //this console.log does not get called, not sure why
  }
);

app.get(
  "/auth/google/callback",
  passport.authenticate("google", {
    successRedirect: "http://localhost:3000/profile",
    failureRedirect: "http://localhost:3000/login",
  }),
  function (req, res) {
    // console.dir(req);
    // Successful authentication, redirect home.
    console.log("redirect to profile"); //this does get called
    res.redirect("http://localhost:3000/profile"); 
  }
);

app.get("/", (req, res) => {
  res.send("Hello world.");
});

app.get("/getuser", (req: any, res: any) => {
  //req should have user thanks to serializer/deserializer
  console.log(req.user); // => returns undefined even after successful authentication
  res.send(req.user);
});

app.listen(PORT, () => {
  console.log(`Server Started on ${PORT}`);
});

为什么不deserializeUser()叫??

4

1 回答 1

3

fetchBaseQuery只是一个fetch带有一些额外选项的包装器。

所以要么

  baseQuery: fetchBaseQuery({
    baseUrl: "http://localhost:4000",
    prepareHeaders(headers) {
      return headers;
    },
    credentials: "include"
  }),

或者

        query: () => {
          return { url: `/getuser`, credentials: "include" };
        },
于 2021-10-04T09:57:09.837 回答