Я создаю систему входа в систему 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
с сервера, чтобы затем продолжить работу оттуда и манипулировать данными пользователя на стороне клиента?