Как связать веб-сокет с пользователем с помощью экспресс-сессии и паспорта? - PullRequest
0 голосов
/ 06 июня 2019

Моя цель здесь - отправлять сообщения в сокеты, принадлежащие пользователям, чтобы пользователи могли видеть только свою информацию или свои пользовательские роли.

До сих пор я пробовал пример кода из ws github и из старых вопросов SO. Идея состоит в том, чтобы передать объект парсера экспресс-сеанса в функцию WebCocket.Server verifyClient. Затем, когда создается новый сокет, я могу связать информацию о сеансе с сокетом. Моя проблема в том, что я не вижу пользователя паспорта при подключении нового сокета, поэтому я, должно быть, допустил ошибку.

Вот часть запроса с информацией о сеансе:

...
session:
   Session {
     cookie:
      { path: '/',
        _expires: 2019-06-06T20:17:56.719Z,
        originalMaxAge: 3600,
        httpOnly: true } } }

Вот то, что я пытался поделиться сессией с веб-сокетами:

const express = require('express'); // 4.13.4
const http = require('http');
const WebSocket = require('ws'); // 7.0.0
const session = require('express-session'); //1.16.1
const pgSession = require('connect-pg-simple')(session); // 5.0.0
const passport = require('passport'); // 0.4.0

const app = express();
const server = http.createServer(app);

let sessionParser = session({
  store: new pgSession({
    conString: secrets.postgres,
    tableName: secrets.sessionTable
  }),
  secret: secrets.sessionSecret,
  saveUninitialized: true,
  resave: false,
  cookie: {
    maxAge: 3600
  }
});

app.use(sessionParser);
app.use(passport.initialize());
app.use(passport.session());

let wss = new WebSocket.Server({
  server: app.listen(8080),
  clientTracking: true,
  verifyClient: (info, done) => {
    console.log("Parsing session info from request...")
    sessionParser(info.req, {}, () => {
      console.log(info.req);
      done(info.req.session);
    })
  }
  }, () => {});

wss.on('connection', (ws, req) => { //, req
  console.log(`WS connected with user ${req}`); //.session.passport.user?
  // ...
});

server.listen(8000);

Редактировать, код паспорта добавлен ниже:

'use strict';

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;

const secrets = require('./secrets');
const db = require('../models');
const UserRepo = require('../repositories/UserRepository');

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  db.User.findByPk(id).then(function(user) {
    done(null, user);
  }).catch(function(error) {
    done(error);
  });
});

/**
 * Sign in using Email and Password.
 */
passport.use(new LocalStrategy({ usernameField: 'email' }, function(email, password, done) {
  email = email.toLowerCase();
  db.User.findUser(email, password, function(err, user) {
    if(err)
      return done(err, null);
    return done(null, user);
  });
}));

/**
 * Login Required middleware.
 */
exports.isAuthenticated = function(req, res, next) {
  if (req.isAuthenticated()) return next();
  res.redirect('/login');
};

/**
 * Authorization Required middleware.
 */
exports.isAuthorized = function(req, res, next) {
  var provider = req.path.split('/').slice(-1)[0];

  if (req.user.tokens[provider]) {
    next();
  } else {
    res.redirect('/auth/' + provider);
  }
};
...