如何在 Node.js 中从请求参数获取经过身份验证的用户到 socket.io

     2023-03-07     129

关键词:

【中文标题】如何在 Node.js 中从请求参数获取经过身份验证的用户到 socket.io【英文标题】:How to get authenticated user from request param to socket.io in Node.js 【发布时间】:2021-10-28 21:22:20 【问题描述】:

几天来,我一直试图弄清楚如何获取当前用户,以便将其传递给 socket.io 发射,但无济于事。我正在使用 Passport.js 进行身份验证、ejs、socket.io、express、MySQL 和 node.js。下面是我的代码。

app.js

const path = require('path');
const express = require("express");
const cookieParser = require('cookie-parser');
const toastr = require('express-toastr');
const cors = require("cors");
const app = express();
const httpServer = require("http").createServer(app);
const io = require("socket.io")(httpServer);
const fileUpload = require('express-fileupload');
const flash = require('connect-flash');
const session = require('express-session');
const passport = require('passport');
const moment = require('moment');
require('dotenv').config();

// Set configuration
app.use(express.urlencoded( extended: true ));
app.use(express.static(path.join(__dirname, 'assets')));
app.use(express.static(path.join(__dirname + '/public')));
app.use(express.static(path.join(__dirname + '/libs')));
app.use(cookieParser(process.env.SECRET_KEY));
app.use(session(
    secret : process.env.SECRET_KEY,
    saveUninitialized : true,
    resave : true
));
app.use(flash());
app.use(toastr());
app.use(cors());
app.use(fileUpload(
    createParentPath: true
));
require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session());
app.use((req, res, next) => 
    res.locals.errors = req.flash('errors');
    res.locals.error = req.flash('error');
    res.locals.success = req.flash('success');
    res.locals.values = req.flash('values');
    res.locals.toastr = req.flash('toastr');
    res.locals.moment = moment;
    next();
);
app.set('view engine', 'ejs');
app.set('views', 'views');

// Local files
const adminRoutes = require('./routes/admin');
const userRoutes = require('./routes/user');
const translatorRoutes = require('./routes/translator');
const authRoutes = require('./routes/auth');
const indexRoutes = require('./routes/index');
const  ensureAuthenticated  = require('./config/authMiddleware');
const User = require('./app/models/user');

io.on("connection", socket => 
    console.log('Socket 1 is connected -- ' + socket.id);
    // socket.on('get-authenticated-user', data => 
    //     console.log(data);
    // );
    socket.on('current-user', (data) => console.log(data));

    socket.on('disconnect', () => 
        console.log('User disconnected');
    );
);

// Routes
app.get('/', ensureAuthenticated, indexRoutes);
app.use('/admin', ensureAuthenticated, adminRoutes);
app.use('/admin', ensureAuthenticated, translatorRoutes);
app.use('/admin', ensureAuthenticated, userRoutes);
// app.get('/users', (req, res) => 
//     const model = new User();
//     model.all([], (err, rows) => 
//         return res.json(rows);
//     );
// );
app.use(indexRoutes);
// app.use('/admin', adminRoutes);
// app.use('/admin', translatorRoutes);
// app.use('/admin', userRoutes);
app.use(authRoutes);

// 404 Page
app.use((req, res) => 
    res.render('404',  pageTitle: '404 Page not found' );
);

httpServer.listen(process.env.PORT);

index.js(路由器)

const express = require('express');
const router = express.Router();
const  getCurrentUser  = require('../config/functions');
const io = require('socket.io');

const socket = io('/');

router.get('/', (req, res) => 
    socket.emit('get-current-user', req.user);
    res.render('welcome',  pageTitle: 'Welcome!', isLogin: false, user: req.user );
);

module.exports = router;

用于身份验证的passport.js

const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');
const db = require('../app/database/database');
const moment = require('moment');
const io = require('socket.io');

module.exports = (passport) => 
    passport.use(new LocalStrategy( usernameField: 'email' , (email, password, done) => 
        db.query('SELECT * FROM users WHERE email = ?', [email], (err, rows, fields) => 
            if (err) throw err;
            if (rows.length <= 0) 
                return done(null, false,  message: 'Email incorrect' );
            
            const user = rows[0];
            bcrypt.compare(password, user.passwd, (errm, isMatch) => 
                if (errm) throw errm;
                if (isMatch) 
                    // io.emit('get-current-user', user);
                    const sql = `UPDATE users SET last_logged_in = ? WHERE email = ?`;
                    db.query(sql, [moment().format(), email], (_, __) => 
                        return done(null, user);
                    );
                 else 
                    return done(null, false,  message: 'Password incorrect' );
                
            );
        );
    ));

    passport.serializeUser((user, done) => 
        done(null, user);
    );
    passport.deserializeUser((user, done) => 
        db.query('SELECT * FROM users WHERE id = ?', [user.id], (err, rows, fields) => 
            if (err) throw err;
            if (rows.length <= 0) 
                return done(null, false,  message: 'Record is not found in our database' );
            
            const setUser = rows[0];
            done(err, setUser);
        );
    );
;

main.js

// Initialization of Socket.io Connection
const socket = io("/");
let user;
function userInfo(u) 
    user = u;

// wss.registerSocketEvents(socket);
socket.on('connect', () => 
    console.log('connecting from client');
    // Test if emitting user is working
    socket.emit('current-user', 
        name: 'Woo Bear',
        email: "woo@live.com",
        socketId: socket.id,
    );
    registerSocketEvents(socket);
);

const getUser = (user) => 
    console.log(user);
;

// webRTCHandler.getLocalPreview();

// // Copy Personal Code - Add Event Listener - Click
// const personalCodeCopyButton = document.getElementById('personal_code_copy_button');
// personalCodeCopyButton.addEventListener('click', () => 
//   const personalCode = store.getState().socketId;
//   navigator.clipboard && navigator.clipboard.writeText(personalCode);
// );

// // Add Event Listener - Chat and Video click
// const personalCodeChatButton = document.getElementById('personal_code_chat_button');
// const personalCodeVideoButton = document.getElementById('personal_code_video_button');
// personalCodeChatButton.addEventListener('click', () => 
//   console.log('chat click');
//   const personalCodeInput = document.getElementById('personal_code_input').value;
//   webRTCHandler.sendPreOffer(constants.callType.CHAT_PERSONAL_CODE, personalCodeInput);
// );

// personalCodeVideoButton.addEventListener('click', () => 
//   console.log('video click');
//   const personalCodeInput = document.getElementById('personal_code_input').value;
//   webRTCHandler.sendPreOffer(constants.callType.VIDEO_PERSONAL_CODE, personalCodeInput);
// );

// // event listeners for video call buttons
// const micButton = document.getElementById('mic_button');
// micButton.addEventListener('click', () => 
//   const localStream = store.getState().locatStream;
//   const micEnabled = localStream.getAudioTracks()[0].enabled;
//   localStream.getAudioTracks()[0].enabled = !micEnabled;
//   ui.updateMicButton(micEnabled);
//   console.log(localStream.getAudioTracks()[0]);
// );

// const cameraButton = document.getElementById('camera_button');
// cameraButton.addEventListener('click', () => 
//   const localStream = store.getState().locatStream;
//   const cameraEnabled = localStream.getVideoTracks()[0].enabled;
//   localStream.getVideoTracks()[0].enabled = !cameraEnabled;
//   ui.updateCameraButton(cameraEnabled);
// );

// const switchForScreenSharingButton = document.getElementById('screen_sharing_button');
// switchForScreenSharingButton.addEventListener('click', () => 
//   const screenSharingActive = store.getState().screenSharingActive;
//   webRTCHandler.switchBetweenCameraAndScreenSharing(screenSharingActive);
// );

// const newMessageInput = document.getElementById('new_message_input');
// newMessageInput.addEventListener('keydown', (event) => 
//   console.log('User types');
//   const key = event.key;

//   if (key === 'Enter') 
//     webRTCHandler.sendMessageUsingDataChannel(event.target.value);
//     ui.appendMessage(event.target.value, true);
//     newMessageInput.value = '';
//   
// );

// const sendMessageButton = document.getElementById('send_message_button');
// sendMessageButton.addEventListener('click', () => 
//   webRTCHandler.sendMessageUsingDataChannel(newMessageInput.value);
//   ui.appendMessage(newMessageInput.value, true);
//   newMessageInput.value = '';
// );

welcome.ejs

<%- include('includes/head.ejs') %>
  <link rel="stylesheet" href="/css/video.css">
  </head>

  <body class="layout-top-nav" style="height: auto;">
    <div class="wrapper">
      <!-- Navbar -->
      <div class="display-none">
        <nav class="main-header navbar navbar-expand-md navbar-dark navbar-primary">
          <div class="container">
            <a href="/" class="navbar-brand">
              <i class="text-white fa fa-desktop" aria-hidden="true"></i>
              <span class="brand-text font-weight-light">GSL Translators</span>
            </a>
            <ul class="order-1 ml-auto order-md-3 navbar-nav navbar-no-expand">
              <li class="nav-item dropdown">
                <a class="nav-link" data-toggle="dropdown" href="#">
                  More
                  <i class="fas fa-caret-down"></i>
                </a>
                <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
                  <div class="dropdown-divider"></div>
                  <a href="/admin/profile" class="dropdown-item">
                    <i class="mr-2 fas fa-phone"></i> Contact
                  </a>
                  <div class="dropdown-divider"></div>
                  <a href="#" class="dropdown-item">
                    <i class="mr-2 fas fa-info"></i> About
                  </a>
                  <div class="dropdown-divider"></div>
                  <a href="/logout" class="dropdown-item">
                    <i class="mr-2 fas fa-power-off" aria-hidden="true"></i></i> Log out
                  </a>
              </li>
            </ul>
          </div>
        </nav>
        <!-- /.navbar -->

        <!-- Content Wrapper. Contains page content -->
        <div class="content-wrapper" style="min-height: 520.5px;">
          <!-- Content Header (Page header) -->
          <div class="content-header">
            <div class="container">

            </div><!-- /.container-fluid -->
          </div>
          <!-- /.content-header -->

          <!-- Main content -->
          <div class="content">
            <div class="container px-2">
              <div class="row">
                <% for (let i=0; i < 4; i++)  %>
                  <div class="col-md-3 col-sm-4 col-sm">
                    <div class="card card-primary r-5 elevation-3">
                      <div class="p-0 card-body box-profile">
                        <div class="text-center">
                          <!-- <img class="profile-user-img img-fluid img-circle" src="img/user4-128x128.jpg"
                            > -->
                          <img src="img/user4-128x128.jpg" class="rt-5" 
                            style="width: 100%; max-height: 13rem;">
                        </div>

                        <div class="p-2 mb-2">
                          <h3 class="text-center profile-username">Cyril Eduafo</h3>

                          <p class="mb-1 text-center text-muted">0501395590</p>
                          <p class="mb-1 text-center text-muted">Available</p>
                          <p class="mb-1 text-center text-muted">
                            <i class="text-orange fa fa-star" aria-hidden="true"></i>
                            <i class="text-orange fa fa-star" aria-hidden="true"></i>
                            <i class="text-orange fa fa-star" aria-hidden="true"></i>
                            <i class="text-orange fa fa-star" aria-hidden="true"></i>
                          </p>

                          <div class="mt-2 text-center">
                            <button class="py-1 rounded btn-call bg-success w-25">
                              <i class="fa fa-video" aria-hidden="true"></i>
                            </button>
                          </div>
                        </div>
                      </div>
                      <!-- /.card-body -->
                    </div>
                  </div>
                  <%  %>
              </div>
              <!-- /.row -->
            </div><!-- /.container-fluid -->
          </div>
          <!-- /.content -->
        </div>
      </div>
      <div id="hidden dialog"></div>
      <%- include('includes/footer.ejs') %>
      <script src="/socket.io/socket.io.js"></script>
    <!-- jQuery -->
    <script src="/js/jquery.min.js"></script>
    <!-- Bootstrap 4 -->
    <script src="/js/bootstrap.bundle.js"></script>
    <!-- AdminLTE App -->
    <script src="/js/adminlte.min.js"></script>
    <script src="/js/sweetalert2.min.js"></script>
    <script src="/js/toastr.min.js"></script>
    <script src="/js/ui-store.min.js"></script>
    <script src='store.js'></script>
    <!-- <script src='elements.js'></script>
    <script src='constants.js'></script>
    <script src='ui.js'></script> -->
    <script src='wss.js'></script>
    <!-- <script src='webRTCHandler.js'></script> -->
    <script src="main.js"></script>
    <script>
      // Get user 
      userInfo(<%= user %>);
    </script>
    <%- typeof toastr != undefined ? toastr : ""%>
  </body>

  </html>

package.json

  
  "name": "gsl_translators",
  "version": "1.0.0",
  "description": "This is for Toah's project work for his MSc ICT",
  "main": "app.js",
  "scripts": 
    "start": "nodemon app.js"
  ,
  "repository": 
    "type": "git",
    "url": "git+https://github.com/ljsharp/gsl_translators.git"
  ,
  "author": "Leslie Joe - LJ Sharp",
  "license": "ISC",
  "bugs": 
    "url": "https://github.com/ljsharp/gsl_translators/issues"
  ,
  "homepage": "https://github.com/ljsharp/gsl_translators#readme",
  "dependencies": 
    "@fabrice8/ui-store": "^1.0.5",
    "bcrypt": "^5.0.1",
    "connect-flash": "^0.1.1",
    "cookie-parser": "^1.4.5",
    "cors": "^2.8.5",
    "dotenv": "^10.0.0",
    "ejs": "^3.1.6",
    "express": "^4.17.1",
    "express-fileupload": "^1.2.1",
    "express-session": "^1.17.2",
    "express-toastr": "^2.0.2",
    "express-validator": "^6.12.1",
    "moment": "^2.29.1",
    "mysql": "^2.18.1",
    "nodemon": "^2.0.12",
    "passport": "^0.4.1",
    "passport-local": "^1.0.0",
    "socket.io": "^4.1.3",
    "storage-manager-js": "^4.0.6",
    "uuidv4": "^6.2.12",
    "validator": "^13.6.0"
  

我需要您的帮助来弄清楚我可以使用什么方法或技巧来获取当前或登录的用户。提前致谢。

【问题讨论】:

请看这个答案***.com/a/36821359/8201020 您可以使用相同的算法和密码来验证令牌。 【参考方案1】:

解决了!!我找到了这篇文章 - Sharing Passport.Js Sessions With Both Express And Socket.Io 我现在可以获得经过身份验证的用户数据。让我放弃修复获取用户信息问题的代码。

添加以下包

const session = require('express-session');
const sessionStore = new session.MemoryStore();
const passportSocketIo = require('passport.socketio');
const passport = require('passport');

app.use(session(
    secret : process.env.SECRET_KEY,
    saveUninitialized : true,
    resave : true,
    key: 'express.sid',
    store: sessionStore
));

io.use(passportSocketIo.authorize(
    store: sessionStore,
    key: 'express.sid',
    passport: passport,
    cookieParser: cookieParser,
    secret: process.env.SECRET_KEY
));
let connectedUsers = [];
io.on("connection", socket => 
    connectedUsers.push(
        ...socket.request.user,
        socketId: socket.id,
    );
    console.log(connectedUsers);
    // socket.on('current-user', (data) => 
    //     const connectedUser = 
    //         ...data,
    //         socketId: socket.id,
    //     ;
    //     connectedUsers.push(connectedUser);
    //     console.log(connectedUsers);
    //     socket.emit('updatedUserLists', connectedUsers);
    // );

    socket.on('disconnect', () => 
        console.log(socket.id);
        connectedUsers = connectedUsers.filter(function(u) 
            console.log(u);
            return u.socketId !== socket.id;
        );
        console.log(connectedUsers);
    );
);

希望这对其他人有所帮助。祝你有美好的一天!

【讨论】:

如何在 node.js 中获取 post 参数? [复制]

】如何在node.js中获取post参数?[复制]【英文标题】:Howtogetpostparameterinnode.js?[duplicate]【发布时间】:2015-01-2213:43:56【问题描述】:我在android中使用Node.jsexpress和httpAsyncClient库。我正在发送请求以表达使用Post包含参数。请求确实... 查看详情

在 Flutter 的下拉列表中从 Firebase 获取经过身份验证的用户列表

】在Flutter的下拉列表中从Firebase获取经过身份验证的用户列表【英文标题】:FetchingAuthenticatedUserslistfromFirebaseinadropdownlistinFlutter【发布时间】:2021-04-1105:42:10【问题描述】:我在使用Flutter开发应用程序时使用Firebase实时数据库。... 查看详情

Node.js:从请求中获取路径

...路径作为参数。例如\'/BackupFolder/toto/tata/titi/myfile.txt\'。如何在我的浏览器上测试这项服务?例如,如何使用Express格式化此请求?ex 查看详情

每次在 Node.js (Express.js) 中发出 API 请求之前,如何简化 Fetching Auth token?

】每次在Node.js(Express.js)中发出API请求之前,如何简化FetchingAuthtoken?【英文标题】:HowdoIsimplifyFetchingAuthtokeneverytimebeforemakingAPIrequestinNode.js(Express.js)?【发布时间】:2021-09-0622:33:09【问题描述】:我的服务需要响应从UI获取请求。... 查看详情

如何在 API REST 中从 Laravel Controller 中的 URL 获取参数 [重复]

】如何在APIREST中从LaravelController中的URL获取参数[重复]【英文标题】:HowtogetparametersfromURLinLaravelController,inanAPIREST[duplicate]【发布时间】:2021-03-1318:38:29【问题描述】:我有一个DDBB,我已经在使用STRAPI,我通过RESTAPI获取数据。我... 查看详情

如何在 Node.js HTTP2 中获取请求正文?

】如何在Node.jsHTTP2中获取请求正文?【英文标题】:HowtogetrequestbodyinNode.jsHTTP2?【发布时间】:2019-08-1002:53:20【问题描述】:我有以下代码,但不知道如何从请求中获取正文:varhttp2=require(\'http2\');varfs=require(\'fs\');varserver=http2.creat... 查看详情

AWS Lambda node.js 中 HTTP 请求的基本身份验证

...正常,但是,我想访问需要用户名/密码身份验证的URL。如何在我的代码中实现它?functionhttprequest() 查看详情

如何在 spring-security-oauth 中获取经过身份验证的用户

】如何在spring-security-oauth中获取经过身份验证的用户【英文标题】:Howtogetauthenticateduserinspring-security-oauth【发布时间】:2013-04-2306:44:31【问题描述】:对于我的REST应用程序,我使用了基本身份验证(发送用户密码并在每个请求... 查看详情

尝试在 node.js 中发出 PUT 请求

】尝试在node.js中发出PUT请求【英文标题】:TryingtomakeaPUTrequestinnode.js【发布时间】:2021-01-0611:39:35【问题描述】:我正在尝试使用Javascript向node.js发出PUT请求。基本上,我想做的是让经过身份验证的用户可以更新电话号码和密码... 查看详情

如何在 Node.js 中从 MongoDB 返回 JSON?

】如何在Node.js中从MongoDB返回JSON?【英文标题】:HowtoreturnJSONfromMongoDBinNode.js?【发布时间】:2016-02-0121:30:54【问题描述】:我有一个名为pokemon的mongodb数据库和一个名为pokemons的集合。这是我尝试编写一个在mongodb中执行find()操作... 查看详情

node.js http获取请求参数[重复]

】node.jshttp获取请求参数[重复]【英文标题】:node.jshttpgetrequestparameters[duplicate]【发布时间】:2013-10-0211:44:36【问题描述】:我想处理这样的HTTP请求:GEThttp://1.2.3.4/status?userID=1234但我无法从中提取参数userID。我正在使用Express,但... 查看详情

如何在 node.js 中要求一个文件并在请求方法中传递一个参数,而不是传递给模块?

】如何在node.js中要求一个文件并在请求方法中传递一个参数,而不是传递给模块?【英文标题】:Howtorequireafileinnode.jsandpassanargumentintherequestmethod,butnottothemodule?【发布时间】:2012-02-0816:31:05【问题描述】:我有一个必须加载的mod... 查看详情

如何在mvc中检查请求是不是经过身份验证?

】如何在mvc中检查请求是不是经过身份验证?【英文标题】:Howtocheckwhetherrequestisauthenticatedornotinmvc?如何在mvc中检查请求是否经过身份验证?【发布时间】:2016-07-0905:45:17【问题描述】:我正在实现一个MVC应用程序,并且使用活... 查看详情

获取“无效参数:redirect_uri”尝试使用 KeyCloak 进行 NODE.JS 身份验证

】获取“无效参数:redirect_uri”尝试使用KeyCloak进行NODE.JS身份验证【英文标题】:Getting"Invalidparameter:redirect_uri"tryingNODE.JSauthenticationwithKeyCloak【发布时间】:2016-09-0401:55:00【问题描述】:我正在使用Node.JS(express)和一个名... 查看详情

在 Linux 上使用 Node JS 进行窗口身份验证

...多个应用程序。我想使用窗口身份验证登录应用程序。我如何在Linux上使用它。我已经与ActiveDirectory建立了联系。我只需要请求用户的当前用户名即可从活动目录中获取用户配置文件。我可以不在IISNODE上 查看详情

在js中从mysql中查询内容

...试使用node.js,我在上面创建了一个服务器,但我找不到如何将它链接到网页。如何在节点中传递参数?我需要根据链接中的参数从表中加载内容。(标题、描述等)例子:本地主机:63342/MySite/project.html?projectn 查看详情

如何在快速路由器获取请求中从节点获取中使用获取

】如何在快速路由器获取请求中从节点获取中使用获取【英文标题】:Howtousefetchfromnode-fetchinsideanexpressroutergetrequest【发布时间】:2021-10-0317:19:01【问题描述】:我正在使用node-fetch从快速路由器获取请求中的github(用户存储库)... 查看详情

如何在状态挂钩中从获取请求中设置数据(对象数组)?

】如何在状态挂钩中从获取请求中设置数据(对象数组)?【英文标题】:Howtosetdata(arrayofobjects)fromgetrequestinastatehook?【发布时间】:2020-11-1405:10:29【问题描述】:您好,我在我的App组件中使用axios获取数据,然后在我的SearchResult... 查看详情