Я использую React-admin в стеке MERN и использую экспресс-сеанс для аутентификации при входе.
Я следовал руководству по настройке базового веб-приложения. Теперь я подключился к бэк-энду и смог войти, что отправляет браузеру куки. требование выглядит следующим образом
Session {
[0] cookie:
[0] { path: '/',
[0] _expires: null,
[0] originalMaxAge: null,
[0] httpOnly: false,
[0] secure: false },
[0] userId: 5baa3e30a46312daaa46b9e7,
[0] email: 'admin@gmail.com',
[0] userRole: 'admin',
[0] first: 'john',
[0] last: 'Doe',
[0] company: undefined }
Однако, когда я console.log (req.session) на другом маршруте, req.session не определен. По какой-то причине, когда я отправляю запрос в бэкэнд, это сеанс не сохраняется? Я новичок в MERN, и я не уверен, как решить эту проблему. Долго смотрел онлайн, и все ответы сводятся к учетным данным cors, которые, я думаю, я уже уладил?
Session {
[0] cookie:
[0] { path: '/',
[0] _expires: null,
[0] originalMaxAge: null,
[0] httpOnly: false,
[0] secure: false } }
Я установил для учетной записи значение true на стороне сервера и authProvider. Но я не уверен, как разрешить использование учетных данных / файлов cookie с помощью httpClient, чтобы это могло быть причиной.
App.js
import React from "react";
import { Admin, Resource, fetchUtils } from "react-admin";
import { ItemList } from "./items";
import { CustomerList } from "./customers";
import { Dashboard } from "./dashboard";
import authProvider from "./authProvider";
import dataProvider from "./dataProvider1";
import { createMuiTheme } from "@material-ui/core/styles";
function getTheme(theme) {
return createMuiTheme({
palette: {
type: theme.paletteType,
background: {
default: theme.paletteType === "light" ? "#ddd" : "#fff"
},
secondary: {
light: "#5f5fc4",
main: "#283593",
dark: "#001064",
contrastText: "#fff"
}
}
});
}
const theme = getTheme({
paletteType: "light"
});
const httpClient = (url, options = {}) => {
if (!options.headers) {
options.headers = new Headers({ Accept: "application/json" });
}
options.withCredentials = true;
return fetchUtils.fetchJson(url, options);
};
const App = () => (
<Admin
theme={theme}
authProvider={authProvider}
dashboard={Dashboard}
dataProvider={dataProvider("http://localhost:5000/api", httpClient)}
>
{/* <Resource
name="posts"
list={PostList}
edit={PostEdit}
create={PostCreate}
icon={PostIcon}
/>
<Resource name="users" list={UserList} icon={UserIcon} /> */}
<Resource
name="items/getAllItems"
options={{ label: "All Items" }}
list={ItemList}
/>
<Resource
name="users/getAllUsers"
options={{ label: "Customer List" }}
list={CustomerList}
/>
</Admin>
);
export default App;
Express server.js
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const session = require("express-session");
const multer = require("multer");
const items = require("./routes/api/items");
const users = require("./routes/api/users");
const bookings = require("./routes/api/bookings");
const app = express();
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Credentials", true);
res.header("Access-Control-Allow-Origin", "http://localhost:3001" || "*");
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
});
//use sessions for tracking logins
app.use(
session({
secret: "work hard",
resave: true,
saveUninitialized: true,
cookie: {
secure: false,
httpOnly: false
}
})
);
// bodyParser Middleware
app.use(bodyParser.json());
// multer parameters
const storage = multer.diskStorage({
destination: function(req, res, cb) {
cb(null, "uploads/");
}
});
const upload = multer({ storage: storage });
// DB config
const db = require("./config/keys").mongoURI;
// connect to mongoDB
mongoose
.connect(db)
.then(() => console.log("MongoDB Connected"))
.catch(err => console.log(err));
// Use routes
app.use("/api/items", items);
app.use("/api/users", users);
app.use("/api/bookings", bookings);
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
Экспресс-маршруты
const express = require("express");
const router = express.Router();
const session = require("express-session");
// User model
const User = require("../../models/User");
const fs = require("fs");
//route im trying to call but keeps giving me 403 ERROR because req.session is undefined
router.get("/getAllUsers", (req, res) => {
console.log(req.session); //undefined
if (req.session.userRole != "admin") {
return res
.status(403)
.json({ success: false, message: "You are not an admin" });
}
User.find()
.sort({ email: -1 })
.then(users => res.json(users));
});
//login route
router.post("/login", (req, res) => {
User.authenticate(req.body.email, req.body.password, function(error, user) {
if (error || !user) {
return res.status(404).json({ success: false, message: error });
} else {
req.session.userId = user._id;
req.session.email = user.email;
req.session.userRole = user.role;
req.session.first = user.name.first;
req.session.last = user.name.last;
req.session.company = user.company;
req.session.save();
console.log(req.session); //gives correct session
return res.status(200).json({ success: true, session: req.session });
}
});
});
module.exports = router;
authProvider.js
import { AUTH_LOGIN, AUTH_LOGOUT, AUTH_ERROR, AUTH_CHECK } from "react-admin";
export default (type, params) => {
// called when the user attempts to log in
if (type === AUTH_LOGIN) {
const { username, password } = params;
const request = new Request("http://localhost:5000/api/users/login", {
method: "POST",
body: `{"email": "${username}", "password": "${password}"}`,
credentials: "include",
headers: new Headers({ "Content-Type": "application/json" })
});
return fetch(request)
.then(response => {
if (response.status < 200 || response.status >= 300) {
throw new Error(response.statusText);
}
return response.json();
})
.then(function(myJson) {
console.log(myJson.session);
localStorage.setItem("session", myJson.session);
});
}
// called when the user clicks on the logout button
if (type === AUTH_LOGOUT) {
localStorage.removeItem("session");
return Promise.resolve();
}
if (type === AUTH_CHECK) {
return localStorage.getItem("session")
? Promise.resolve()
: Promise.reject({ redirectTo: "/login" });
}
return Promise.reject("Unknown method");
};