英文:
Express-session + passport creating a session on every request
问题
I understand that you want a translation of the code you provided. Here's the translated code:
app.js:
import express from "express";
import mongoose from "mongoose";
import { Server } from "socket.io";
import { boxRouter } from "./routes/box.router.js";
import { productRouter } from "./routes/product.router.js";
import { cartRouter } from "./routes/cart.router.js";
import { userRouter, isLoggedIn } from "./routes/user.router.js";
import passport from "passport";
import initializePassport from "./passport.config.js";
import cors from 'cors';
import MongoStore from "connect-mongo";
import cookieParser from "cookie-parser";
import session from "express-session";
export var app = express();
const httpServer = app.listen(8080, () => { console.log("Server Up"); });
export const socketServer = new Server(httpServer);
app.use(cookieParser("mostsecretsecret"));
app.use(session({
store: MongoStore.create({
mongoUrl: 'blablabla',
mongoOptions: { useNewUrlParser: true, useUnifiedTopology: true },
ttl: 15
}),
cookie: {
maxAge: 7 * 24 * 60 * 60 * 1000,
},
secret: 'mysecret',
resave: true,
saveUninitialized: false
}));
initializePassport();
app.use(passport.initialize());
app.use(passport.session());
app.use(cors());
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use('/api/boxes', boxRouter);
app.use('/api/products', productRouter);
app.use('/api/carts', cartRouter);
app.use('/api/users', userRouter);
var connectionString = "blablabla";
mongoose.set('strictQuery', false);
mongoose.connect(connectionString);
socketServer.on('connection', socket => {
console.log("Nuevo cliente conectado.");
});
passport.config.js:
import passport from "passport";
import local from 'passport-local';
import { userModel } from './models/user.model.js';
import { createHash, isValidPassword } from "./utils.js";
import { cartManager } from "./managers/CartManager.js";
const LocalStrategy = local.Strategy;
const initializePassport = () => {
passport.use('register', new LocalStrategy(
{ passReqToCallback: true, usernameField: 'email' }, async (req, username, password, done) => {
const { first_name, last_name, email, newsletter } = req.body;
try {
let user = await userModel.findOne({ email: username });
if (user) {
console.log("El usuario ya existe");
return done(null, false);
}
let newCart = await cartManager.createCart();
const newUser = {
first_name,
last_name,
email,
password: createHash(password),
cartId: newCart.id,
newsletter,
role: 'user'
};
let result = await userModel.create(newUser);
return done(null, result);
} catch (err) {
return done("Error al obtener el usuario: " + err);
}
}
));
passport.use('login', new LocalStrategy(
{ usernameField: 'email' }, async (username, password, done) => {
try {
const user = await userModel.findOne({ email: username });
if (!user) {
console.log("El usuario no existe");
return done(null, false);
}
if (!isValidPassword(user, password)) return done(null, false);
return done(null, user);
} catch (err) {
return done(err);
}
}
));
passport.serializeUser((user, done) => {
done(null, user._id);
});
passport.deserializeUser(async (id, done) => {
let user = await userModel.findById(id);
done(null, user);
});
}
export default initializePassport;
user.router.js:
import { Router } from 'express';
import passport from 'passport';
export const userRouter = Router();
export function isLoggedIn(req, res, next) {
if (req.session.user) {
return next();
}
return res.status(401).send('Error de autorización.');
}
userRouter.post('/register', passport.authenticate('register', {}), async (req, res) => {
try {
res.send('Success');
} catch (error) {
res.status(400).send({
status: 'error',
message: error.message
});
}
});
userRouter.post('/login', passport.authenticate('login', {}), async (req, res) => {
try {
if (!req.user) {
return res.status(401);
}
req.session.user = {
first_name: req.user.first_name,
last_name: req.user.last_name,
email: req.user.email,
role: req.user.role
};
res.send('Success');
} catch (error) {
res.status(400).send({
status: 'error',
message: error.message
});
}
});
userRouter.get('/logout', (req, res) => {
try {
req.session.destroy(err => {
if (err) res.status(500);
});
} catch (error) {
res.status(400).send({
status: 'error',
message: error.message
});
}
});
userRouter.get('/check-login', isLoggedIn, (req, res) => {
try {
res.status(200).send('Usuario logueado');
} catch (error) {
res.status(400).send({
status: 'error',
message: error.message
});
}
});
Please note that I've provided translations for the code comments and strings as well.
英文:
I'm making both front and back-end of my e-commerce. I'm using express and passport to make a little login and register system. My problem is that whenever I enter any page of my site that involves a request, a new session is created and therefore, sent to my MongoDB server. Let's say I navigate through 3 sections of my site, 3 different sessions are created.
My intention is for the session to be created ONLY after the user logs in.
Here is my code:
app.js:
import express from "express"
import mongoose from "mongoose"
import { Server } from "socket.io"
import { boxRouter } from "./routes/box.router.js"
import { productRouter } from "./routes/product.router.js"
import { cartRouter } from "./routes/cart.router.js"
import { userRouter, isLoggedIn } from "./routes/user.router.js"
import passport from "passport"
import initializePassport from "./passport.config.js"
import cors from 'cors'
import MongoStore from "connect-mongo"
import cookieParser from "cookie-parser"
import session from "express-session"
// const hostname = '0.0.0.0'
// const port = '10000'
export var app = express()
// const httpServer = app.listen(port, hostname, ()=>{ console.log("Server Up")})
const httpServer = app.listen(8080, ()=>{ console.log("Server Up")})
export const socketServer = new Server(httpServer)
app.use(cookieParser("mostsecretsecret"))
app.use(session({
store: MongoStore.create({
mongoUrl: 'blablabla',
mongoOptions: {useNewUrlParser: true, useUnifiedTopology: true},
ttl: 15
}),
cookie:{
maxAge: 7 * 24 * 60 * 60 * 1000,
},
secret: 'mysecret',
resave: true,
saveUnitialized: false
}))
initializePassport()
app.use(passport.initialize())
app.use(passport.session())
app.use(cors())
app.use(express.urlencoded({extended:true}))
app.use(express.json())
app.use('/api/boxes', boxRouter)
app.use('/api/products', productRouter)
app.use('/api/carts', cartRouter)
app.use('/api/users', userRouter)
var connectionString = "blablabla"
mongoose.set('strictQuery', false)
mongoose.connect(connectionString)
socketServer.on('connection', socket=>{
console.log("Nuevo cliente conectado.")
})
passport.config.js:
import passport from "passport";
import local from 'passport-local';
import { userModel } from './models/user.model.js'
import { createHash, isValidPassword } from "./utils.js";
import { cartManager } from "./managers/CartManager.js";
const LocalStrategy = local.Strategy
const initializePassport = ()=>{
passport.use('register', new LocalStrategy(
{passReqToCallback: true, usernameField: 'email'}, async(req, username, password, done)=>{
const { first_name, last_name, email, newsletter } = req.body
try{
let user = await userModel.findOne({email: username})
if(user){
console.log("El usuario ya existe")
return done(null, false)
}
let newCart = await cartManager.createCart()
const newUser = {
first_name,
last_name,
email,
password: createHash(password),
cartId: newCart.id,
newsletter,
role: 'user'
}
let result = await userModel.create(newUser)
return done(null, result)
}catch(err){
return done("Error al obtener el usuario: " + err)
}
}
))
passport.use('login', new LocalStrategy(
{usernameField: 'email'}, async(username, password, done)=>{
try{
const user = await userModel.findOne({email: username})
if(!user){
console.log("El usuario no existe")
return done(null, false)
}
if(!isValidPassword(user,password)) return done(null, false)
return done(null, user)
}catch(err){
return done(err)
}
}
))
passport.serializeUser((user, done)=>{
done(null, user._id)
})
passport.deserializeUser(async(id, done)=>{
let user = await userModel.findById(id)
done(null, user)
})
}
export default initializePassport
user.router.js:
import { Router } from 'express';
import passport from 'passport';
export const userRouter = Router()
export function isLoggedIn(req, res, next){
if(req.session.user){
return next()
}
return res.status(401).send('Error de autorización.')
}
userRouter.post('/register', passport.authenticate('register', {}), async (req, res)=>{
try {
res.send('Success')
} catch (error) {
res.status(400).send({
status: 'error',
message: error.message
})
}
})
userRouter.post('/login', passport.authenticate('login', {}), async (req, res)=>{
try {
if(!req.user){
return res.status(401)
}
req.session.user = {
first_name: req.user.first_name,
last_name: req.user.last_name,
email: req.user.email,
role: req.user.role
}
res.send('Success')
} catch (error) {
res.status(400).send({
status: 'error',
message: error.message
})
}
})
userRouter.get('/logout', (req, res)=>{
try {
req.session.destroy(err=>{
if(err) res.status(500)
})
} catch (error) {
res.status(400).send({
status: 'error',
message: error.message
})
}
})
userRouter.get('/check-login', isLoggedIn, (req, res) => {
try {
res.status(200).send('Usuario logueado');
} catch (error) {
res.status(400).send({
status: 'error',
message: error.message
})
}
});
I've read multiple posts here and some said to use withCredentials whenever using axios request, but that's not working.
Also, saveUninitalized doesn't work either because passport inserts an empty object into the cookie(i think? smth like that) and that makes them "modified".
This is my database after browsing through 3 pages of my site:
https://i.stack.imgur.com/4rki3.png
答案1
得分: 0
I included this in my app.js file:
我将以下内容包含在我的app.js文件中:
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true,
}
app.use(cors(corsOptions));
And also added "withCredentials: true" to every axios request (I guess there's an option to set it as default but nevermind.)
并且我还在每个axios请求中添加了"withCredentials: true"(我猜有一种设置它为默认选项的方式,但没关系。)
let response = await axios.get("http://localhost:8080/api/boxes", {withCredentials: true })
英文:
OK I fixed it after reading through several posts.
I included this in my app.js file:
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true,
}
app.use(cors(corsOptions));
And also added "withCredentials: true" to every axios request (I guess there's an option to set it as default but nevermind.)
let response = await axios.get("http://localhost:8080/api/boxes", {withCredentials: true })
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论