Express/Passport 创建会话但不向前端发送 cookie

Posted

技术标签:

【中文标题】Express/Passport 创建会话但不向前端发送 cookie【英文标题】:Express/Passport creating session but not sending cookie to front end 【发布时间】:2020-09-17 16:01:21 【问题描述】:

现在我有一个 react 和 node.js 项目正在运行。

客户端(反应应用)-http://localhost:3000 服务器端(Node.js) - http:..localhost:5000

我目前正在尝试实现用户身份验证会话。到目前为止,它将用户名、密码和电子邮件(注册时)发送到服务器。然后服务器将解析数据并尝试注册/登录用户。用户凭证存储在 MongoDB atlas 数据库中。如果成功,它将信息发送回服务器。

验证成功后,服务器应该创建一个会话和 cookie 对。会话将被存储,cookie 将被发送到客户端。但是,后半部分没有发生。我知道会话已成功创建,因为它存储在 MongoDB 的另一个数据库中,但无论我做什么,我似乎都无法将 cookie 发送到前端。

用户模型

const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');
const passportLocalMongoose = require('passport-local-mongoose');
const bcrypt = require('bcrypt');
const SALT_WORK_FACTOR = 10;
const userSchema = new mongoose.Schema(
    username:
        type: String,
        lowercase:true,
        unique: true,
        required:[true, 'Username is required'], 
        match:[/^[a-zA-Z0-9]+$/, 'is an invalid username'],
        index: true
    ,
    password:
        type: String,
        required:[true, 'Password is required']
    ,
    email:
        type:String,
        lowercase:true,
        unique:true,
        required:[true, 'Email is required'],
        match:[/\S+@\S+\.\S+/, 'is an invalid email'],
        index: true, 
        uniqueCaseInsensitive: true
    
, timestap: true)

userSchema.plugin(uniqueValidator, message: 'PATH is already taken.');


//encrypt the password
userSchema.pre('save', function(next) 
    var user = this;
// only hash the password if it has been modified (or is new)
if (!user.isModified('password')) return next();

// generate a salt
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) 
    if (err) return next(err);

    // hash the password using our new salt
    bcrypt.hash(user.password, salt, function(err, hash) 
        if (err) return next(err);

        // override the cleartext password with the hashed one
        console.log("hashedPassword stored");
        user.password = hash;
        next();
    );
);
);

//validatePassword
userSchema.methods.comparePassword = function(candidatePassword, cb) 
    bcrypt.compare(candidatePassword, this.password, function(err, isMatch) 
        if (err) return cb(err);
        cb(null, isMatch);
    );
;



userSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model('users', userSchema, 'userInfo');

authRouter.js

router.post("/register-login",
            //this section checks the authentication
        (req, res, next) =>

            passport.authenticate('local'
            ,   
               successRedirect: '/',
                failureRedirect: '/listingsForm'
            
            ,
            //this will be called if authenticate was successful
            (err, user, info) => 
                if(req.body.isSignUp)

                    if(err)
                        return res.status(400).json(errors:err);
                    
                    if(!user)

                        return res.status(400).json(errors:info);
                    
                    else   

                        return res.status(200).json(success: `created $user.username`);
                    
                
                else
                    if(err)
                        return res.status(400).json(errors:err);
                    
                    if(!user)
                        return res.status(400).json(errors:info);
                    
                    else
                        console.log(user.id);
                        req.login(user, (err)=>
                            if(err)
                                throw err;
                            
                        );
                        return res.status(200).json(success:`Welcome back $user.username`);
                    
                
            )(req,res,next)
        

authUser.js


const User = require('../schemes/User')
const passport = require('passport');
const LocalStrategy = require('passport-local');

passport.serializeUser((user,done) =>
    console.log(user.id);
    done(null,user.id);
)

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

passport.use(
    new LocalStrategy(

        
            usernameField: 'username',
            passwordField: 'password',
            passReqToCallback: true
        ,

        (req, username, password, done) =>

        // console.log(username, password);
        console.log(req.body);
        //For Register  
        if(req.body.isSignUp)
            //determine it is a register attempt
            const newUser = new User(
            username: username,
            password: password,
            email: req.body.email
            );



            newUser.save()
            .then(
                user => 

                    return done(null,user);
                
            )
            .catch(
                err => 
                    console.log('there is error');
                    console.log(err);
                    return done(null, false, message:err.message);
                
            )
        

        //For Login
        else
            User.findOne(username: username)
            .then(user => 

                let attemptPassword = password;
                if(!user)
                    return done(null, false, message:'This username/password does not exist')
                
                else
                    console.log("will verify now");

                    user.comparePassword(attemptPassword, function(err, isMatch) 
                        if (err)
                            console.log('hihi');

                            return done(null, false, message:err)
                        
                        if(!isMatch)

                            return done(null, false, message:'This username/password does not exist')
                        
                        return done(null, user), message:'Successfully Logged In';
                    );
                

            )
        
      
));

module.exports = passport;

索引.js

app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded( extended: true ));

//expression session
app.use(session(
    secret: 'secret',
    resave: false,
    saveUninitialized: true,
    store: new MongoStore(mongooseConnection:mongoose.connection)
  ))

app.use(passport.initialize());
app.use(passport.session());
//express-router
const authRouter = require('./routes/auth-router');

app.use('/users',authRouter);


server.listen(PORT, () => console.log(`Server has started on port $PORT`));

【问题讨论】:

Henry,你有没有找到解决这个问题的方法?我正要发布几乎相同的问题。 【参考方案1】:

我猜 app.use(cors(credentials:true));会解决你的问题的,gyus。

【讨论】:

以上是关于Express/Passport 创建会话但不向前端发送 cookie的主要内容,如果未能解决你的问题,请参考以下文章

使用 Passport.js、express-session 和 express-mysql-session 进行用户身份验证

Angular/Node/Express/Passport 跨域问题 - 启用 CORS Passport Facebook 身份验证

用户未定义:Nodejs/Express + Passport

Node + Express + Passport + Mongoose:req.user 未定义

Express + Passport.js:req.user 未定义

Express、Passport 和 JSON Web 令牌 (jwt) 身份验证