簡體   English   中英

[Express][Nodejs] 如何在 socket.io 連接期間解密 express-session cookie?

[英][Express][Nodejs] How to decrypt express-session cookie during socket.io connection?

登錄成功后,用戶的 userId 和 Name 保存在 cookie 中。

服務器.js

const io = require('socket.io')(http)
const session = require('express-session')


const Allusers = [ {id: 1, name: 'Admin', username: 'admin', password: 'admin'} ]
const socketName = {}

app.use(session({
    name: 'sid',
    resave: false,
    saveUninitialized: false,
    secret: 'secretCode!',

    cookie: {
        httpOnly: false,    
        maxAge: 1000 * 60 * 60 * 24 * 30, // 1  month
        sameSite: true
    }
}))


// FOR USER LOGIN AND SAVING COOKIE
app.post('/login', (req,res) =>{

    const {username, password} = req.body

    if (username && password){

        const user = Allusers.find(user => user.username === username && user.password === password)
        if (user){
            req.session.userId = user.id
            req.session.name = user.name
            return res.redirect('/')
        }

    }
    res.redirect('/login')
})





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

    //   I WANT TO GET NAME AND ID OF THE USER FROM COOKIE, THEN ADD THEM TO socketName as
    //   {'socket_id' : 'Name of the user'}

});

我想從cookie中獲取用戶的nameid ,然后將它們添加到socketname

{'socket_id': '用戶名'}

我可以使用socket.handshake.headers.cookie獲取 cookie,但它是使用秘密字符串加密的。

如何解密 cookie 數據或從Allusers驗證用戶?

對於您的情況,首先,您需要知道 session id 是由生成 function - generateSessionId (默認情況下)生成的。 這意味着 session id( sid cookie) 不包含任何用戶數據,用戶數據存儲在服務器端(默認為MemoryStore )。 因此,您應該從服務器端獲取用戶 session 數據,而不是從sid cookie 中獲取它們。

操作如下:

req.session.userId = userId;
req.session.name = name;

userIdname將存儲在服務器端的MemoryStore中。

現在,讓我們獲取 session 數據。 socket.request.headers.cookie的值將是這樣的字符串:

sid=s%3AfWB6_hhm39Z7gDKvAYFjwP885iR2NgIY.uT80CXyOKU%2Fa%2FxVSt4MnqylJJ2LAFb%2B770BItu%2FpFxk; io=msngndIn0v4pYk7DAAAU
  1. 我們應該使用cookie.parse(str, options)方法將字符串解析為 JavaScript 普通 object。
{
  sid: 's:fWB6_hhm39Z7gDKvAYFjwP885iR2NgIY.uT80CXyOKU/a/xVSt4MnqylJJ2LAFb+770BItu/pFxk',
  io: 'eeOnxhDIiPSE_0gfAAAm'
}
  1. 我們應該使用cookieParser.signedCookie(str, secret)方法取消簽名的 cookie。 獲取未簽名的sid
fWB6_hhm39Z7gDKvAYFjwP885iR2NgIY
  1. Since the default server-side session storage is MemoryStore , you need to initialize it explicitly and call store.get(sid, callback) in the WebSocket connection callback function to get the user session data by sid .

完整的工作示例:

const session = require('express-session');
const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const cookie = require('cookie');

const Allusers = [{ id: 1, name: 'Admin', username: 'admin', password: 'admin' }];
const MemoryStore = new session.MemoryStore();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(
  session({
    store: MemoryStore,
    name: 'sid',
    resave: false,
    saveUninitialized: false,
    secret: 'secretCode!',

    cookie: {
      httpOnly: false,
      maxAge: 1000 * 60 * 60 * 24 * 30,
      sameSite: true,
    },
  }),
);

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  console.log(username, password);
  if (username && password) {
    const user = Allusers.find((user) => user.username === username && user.password === password);
    console.log(user);
    if (user) {
      req.session.userId = user.id;
      req.session.name = user.name;
      return res.redirect('/');
    }
  }
  res.redirect('/login');
});

io.on('connection', (socket) => {
  console.log('a user connected');
  const cookieString = socket.request.headers.cookie;
  console.log('cookieString:', cookieString);
  if (cookieString) {
    const cookieParsed = cookie.parse(cookieString);
    console.log('cookieParsed:', cookieParsed);
    if (cookieParsed.sid) {
      const sidParsed = cookieParser.signedCookie(cookieParsed.sid, 'secretCode!');
      console.log(sidParsed);
      MemoryStore.get(sidParsed, (err, session) => {
        if (err) throw err;
        console.log('user session data:', JSON.stringify(session));
        const { userId, name } = session;
        console.log('userId: ', userId);
        console.log('name: ', name);
      });
    }
  }
});

http.listen(3000, () => {
  console.log('listening on *:3000');
});

您將獲得 session 數據userIdname ,如下所示:

user session data: {"cookie":{"originalMaxAge":2592000000,"expires":"2021-02-14T08:31:50.959Z","httpOnly":false,"path":"/","sameSite":true},"userId":1,"name":"Admin"}
userId:  1
name:  Admin

源代碼: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/62407074

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM