Express-session + passport 在每个请求上创建一个会话。

huangapple go评论97阅读模式
英文:

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 })

huangapple
  • 本文由 发表于 2023年8月5日 04:31:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76838959.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定