Невозможно получить Passport. js req.user из React. js после входа в систему - PullRequest
1 голос
/ 14 июля 2020

Я создаю систему входа в систему MERN с использованием Passport. js. Я настроил все основы Passport. js для правильной работы на стороне сервера вместе с промежуточным программным обеспечением аутентификации для защиты маршрутов.

Поскольку это проект MERN, я использую React в качестве своего клиента -side приложение мне нужно делать вызовы API на бэкэнд. Но я заметил, что я не могу получить доступ к req.user из бэкэнда, пытаясь получить конечную точку /auth/user моего express сервера.

Пока я не могу получить доступ к req.user ни из моего приложения React, ни из программы вызовов API, такой как Insomnia, я могу получить к нему доступ, вручную перейдя в http://localhost:5000/auth/user в браузере.

СЕРВЕР:

индекс. js

const express = require('express');
const mongoose = require('mongoose');
const dotenv = require('dotenv');
const morgan = require('morgan');
const cors = require('cors');
const passport = require('passport');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const connectDB = require('./config/db');

dotenv.config({ path: './config/config.env' });

require('./config/passport')(passport);

const app = express();

app.use(
  session({
    secret: 'keyboard',
    resave: false,
    saveUninitialized: false,
    // cookie: {
    //   secure: true,
    // },
    store: new MongoStore({
      mongooseConnection: mongoose.connection,
      collection: 'sessions',
    }),
  })
);

app.use(passport.initialize());
app.use(passport.session());

app.use(cors());

app.use(express.json());

app.use(
  express.urlencoded({
    extended: false,
  })
);

app.use(morgan('dev'));

connectDB();

app.use('/', require('./routes/index'));
app.use('/auth', require('./routes/auth'));

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
  console.log(
    `Server is running in ${process.env.NODE_ENV} mode on port ${PORT}`
  );
});

конфигурация / паспорт. js

const GoogleStrategy = require('passport-google-oauth20').Strategy;
const mongoose = require('mongoose');
const User = require('../models/User');

module.exports = (passport) => {
  passport.use(
    new GoogleStrategy(
      {
        clientID: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        callbackURL: '/auth/google/callback',
      },
      async (accessToken, refreshToken, profile, done) => {
        const newUser = {
          googleId: profile.id,
          displayName: profile.displayName,
          firstName: profile.name.givenName,
          lastName: profile.name.familyName,
          image: profile.photos[0].value,
        };

        try {
          let user = await User.findOne({
            googleId: profile.id,
          });

          if (user) {
            done(null, user);
          } else {
            user = await User.create(newUser);
            done(null, user);
          }
        } catch (err) {
          console.error(err);
        }
      }
    )
  );

  passport.serializeUser((user, done) => {
    done(null, user.id);
  });

  passport.deserializeUser((id, done) => {
    User.findById(id, (err, user) => {
      done(err, user);
    });
  });
};

маршруты / аутентификация js

const express = require('express');
const passport = require('passport');
const { ensureAuth } = require('../middleware/auth');
const router = express.Router();

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

router.get(
  '/google/callback',
  passport.authenticate('google', {
    failureRedirect: 'http://localhost:3000/login',
  }),
  (req, res) => {
    console.log('/google/callback router:', req.user);
    res.redirect('http://localhost:3000/dashboard');
  }
);

router.get('/user', ensureAuth, (req, res, next) => {
  if (req.user) {
    res.status(200).send(req.user);
  } else {
    res.status(200).send({});
  }
});

router.get('/logout', (req, res) => {
  req.logout();
  res.redirect('http://localhost:3000');
});

module.exports = router;

middleware / auth. js

module.exports = {
  ensureAuth: function (req, res, next) {
    if (req.isAuthenticated()) {
      return next();
    } else {
      res.redirect('http://localhost:3000/login');
    }
  },
  ensureGuest: function (req, res, next) {
    if (req.isAuthenticated()) {
      res.redirect('http://localhost:3000/dashboard');
    } else {
      return next();
    }
  },
};

КЛИЕНТ:

/ client / src / components / page / Login. js

import React from 'react';

const Login = () => {
  return (
    <>
      <a
        style={{
          border: '1px solid #0000ff',
          borderRadius: '4px',
          margin: '40px',
          display: 'table',
          padding: '5px',
          fontWeight: '900',
          color: '#0000ff',
          textDecoration: 'none',
        }}
        href='http://localhost:5000/auth/google'
      >
        Login with Google
      </a>
    </>
  );
};

export default Login;

/ client / src / components / page / Dashboard. js

import React, { useEffect, useState } from 'react';

const Dashboard = () => {
  const [userInfo, setUserInfo] = useState({});

  useEffect(() => {
    const fetchUserInfo = async () => {
      const response = await fetch('http://localhost:5000/auth/user', {
        method: 'GET',
        mode: 'cors',
        cache: 'no-cache',
        credentials: 'same-origin',
        headers: {
          'Content-Type': 'application/json',
        },
      });
      const data = await response.json();
      setUserInfo(data);
    };
    fetchUserInfo();
  }, []);

  const fetchLogout = async () => {
    const response = await fetch('http://localhost:5000/auth/logout', {
      method: 'GET',
      mode: 'cors',
      cache: 'no-cache',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json',
      },
    });
    const data = await response.json();
    setUserInfo(data);
  };

  return (
    <div>
      <h1>Dashboard</h1>
      <button
        onClick={() => {
          fetchLogout();
        }}
      >
        Logout
      </button>
    </div>
  );
};

export default Dashboard;

Любые мысли о том, как получить доступ к req.user с сервера, чтобы затем продолжить работу оттуда и манипулировать данными пользователя на стороне клиента?

...