sockiet.ion Passport.js,express.js和身份验证标头

问题描述

直到最近,我的chrome扩展程序都可以正常工作。

我最初收到一条错误消息

required same site none and secure in the header

然后我将其添加到我的express.session配置中,

 samesite:none,secure:true

现在,不是那个错误,我无法通过使用我的chrome扩展名登录来访问我的网站,我相信这是由于socket.io不维护身份验证cookie。

我的快递服务器如下,

const config = require('../../config');

const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server,{ wsEngine: 'ws' });
const MysqL = require('MysqL');
const expressSession = require('express-session');
const ExpressMysqLSessionStore = require('express-MysqL-session')(expressSession);
const sharedsession = require('express-socket.io-session');
const path = require('path');

const utils = require('./utils');

// remove from header "X-Powered-By: Express"
app.disable('x-powered-by');

server.listen(config.serverParams.port,config.serverParams.address,() => {
    console.log(`Server running at http://${server.address().address}:${server.address().port}`);
});

/* DATABASE */
global.db = MysqL.createConnection(config.db);
db.connect();
/* DATABASE */

/* SESSION */
const sessionStore = new ExpressMysqLSessionStore(config.sessionStore,db);
const session = expressSession({
    ...config.session,store: sessionStore,});
app.use(session);
/* SESSION */

app.use(express.static(config.frontendDir));

app.get([
    '/signup','/stats','/pay',],(req,res) => res.sendFile(path.join(`${config.frontendDir}${req.path}.html`)));

io.use(sharedsession(session,{
    autoSave: true
}));

io.on('connection',socket => {

    socket.use((packet,next) => {
        if (packet[0]) {
            console.log('METHOD:',packet[0]);
            const sessionData = socket.handshake.session.user;
            const noSessionNeed = [ 'login','signup','checkAuth' ].includes(packet[0]);
            let error;
            if ( ! sessionData && ! noSessionNeed) error = { code: -1,message: 'You need to login in extension!' };
            if (error) return next(new Error(JSON.stringify(error)));
            else next();
        }
    });

    const auth = require('./auth')(socket);
    socket.on('checkAuth',auth.checkAuth);
    socket.on('login',auth.login);
    socket.on('signup',auth.signup);
    socket.on('logout',auth.logout);

    const users = require('./users')(socket);
    socket.on('users.get',users.get);

    const sentiment = require('./sentiment')(socket);
    socket.on('sentiment.get',sentiment.get);
    socket.on('sentiment.set',sentiment.set);

    socket.on('disconnect',() => {

    });

});

配置文件有点像这样

config.session = {
        // globals.config.express.sessionSecret
        resave: true,saveUninitialized: true,cookie: {
                maxAge: 86400000,/* FOR WORK ON LOCALHOST
                secure: true,sameSite: 'lax',*/
                sameSite:"None",secure:true,domain: '.xx.xx',},

这是使用socket.io进行身份验证的方式

const passport = require('passport');
/* PAsspORT */
require('./passport')(passport); // pass passport for configuration
/* app.use(passport.initialize());
app.use(passport.session()); */
/* PAsspORT */

const utils = require('./utils');

const bcrypt = require('bcrypt');
const saltRounds = 10;

module.exports = socket => {

    this.checkAuth = fn => {
        if (fn) fn();
    };

    this.login = (params,fn) => {
        passport.authenticate('local-login',(err,user) => {
            const response = {};
            if (user) {
                socket.handshake.session.user = user;
                socket.handshake.session.save();
                response.message = 'Your successful login!';
                response.data = {
                    id: user.id,username: user.username,};
            }
            else if (err) {
                response.error = {
                    code: err,message: ''
                };
                if (err == -1) response.error.message = 'Incorrect username or password!';
            }
            if (fn) fn(response);
        })({ body: params });
    },// socket.on('signup',(params,fn) => {
    this.signup = (params,fn) => {
        passport.authenticate('local-signup',user) => {
            const response = {};
            if (user) {
                console.log('signup',user);
                response.message = 'Your successful signup!';
            }
            else if (err) {
                response.error = {
                    code: err,message: ''
                };
                if (err == -1) response.error.message = 'User alreay exist!';
            }
            if (fn) fn(response);
        })({ body: params });
    };

    // socket.on('logout',fn => {
    this.logout = fn => {
        delete socket.handshake.session.user;
    };

    return this;

};

实用程序

module.exports = socket => {

    // socket.on('users.get',fn => {
    this.get = fn => {
        if (fn) {
            const response = {};
            response.data = {
                id: socket.handshake.session.user.id,username: socket.handshake.session.user.username,};
            fn(response);
        }
    };

    return this;

};

希望能够解决这个问题:P

谢谢!

解决方法

此问题是通过使用与此分离的JWT令牌来解决的,以解决socket.io会话的问题。

,

也许与注册功能有关?我认为对于初学者来说没有注册选项。尝试使if (user)-> if (!user)