সকেট.আইও প্রমাণীকরণ


123

আমি নোড.জেএসে সকেট.আইও ব্যবহার করার চেষ্টা করছি এবং সকেট.আইও ক্লায়েন্টগুলির প্রত্যেককে সার্ভারকে একটি পরিচয় দেওয়ার অনুমতি দেওয়ার চেষ্টা করছি। যেহেতু সকেট কোডটি HTTP সার্ভার কোডের আওতার বাইরে রয়েছে, প্রেরিত অনুরোধ তথ্যে এটির সহজে প্রবেশাধিকার নেই, তাই আমি ধরে নিচ্ছি সংযোগের সময় এটি প্রেরণ করা প্রয়োজন। সবচেয়ে ভাল উপায় কি

1) সকেট.আইওর মাধ্যমে কে সংযুক্ত হচ্ছে সে সম্পর্কে সার্ভারে তথ্য পান

2) তারা কাকে বলে তা প্রমাণীকরণ করুন (আমি বর্তমানে এক্সপ্রেস ব্যবহার করছি, যদি এটি কিছু সহজ করে তোলে)

উত্তর:


104

কানেক্ট-রেডিস ব্যবহার করুন এবং সমস্ত অনুমোদনপ্রাপ্ত ব্যবহারকারীদের জন্য আপনার সেশন স্টোর হিসাবে পুনরায় করুন। প্রমাণীকরণের বিষয়ে নিশ্চিত হয়ে নিন যে আপনি ক্লায়েন্টকে কী (সাধারণত req.sessionID) প্রেরণ করেন। ক্লায়েন্টকে এই কীটি কোনও কুকিতে সংরক্ষণ করুন।

সকেটে সংযোগে (বা পরে যে কোনও সময়) কুকি থেকে এই কীটি আনুন এবং এটিকে আবার সার্ভারে প্রেরণ করুন। এই কীটি ব্যবহার করে পুনরায় redes এ সেশন তথ্য আনুন। (কী পান)

উদাহরণ:

সার্ভার সাইড (সেশন স্টোর হিসাবে redis সহ):

req.session.regenerate...
res.send({rediskey: req.sessionID});

মক্কেলের পক্ষে:

//store the key in a cookie
SetCookie('rediskey', <%= rediskey %>); //http://msdn.microsoft.com/en-us/library/ms533693(v=vs.85).aspx

//then when socket is connected, fetch the rediskey from the document.cookie and send it back to server
var socket = new io.Socket();

socket.on('connect', function() {
  var rediskey = GetCookie('rediskey'); //http://msdn.microsoft.com/en-us/library/ms533693(v=vs.85).aspx
  socket.send({rediskey: rediskey});
});

সার্ভারের দিক:

//in io.on('connection')
io.on('connection', function(client) {
  client.on('message', function(message) {

    if(message.rediskey) {
      //fetch session info from redis
      redisclient.get(message.rediskey, function(e, c) {
        client.user_logged_in = c.username;
      });
    }

  });
});

3
এই সম্পর্কে একটি নতুন আকর্ষণীয় লিঙ্ক আছে> ড্যানিয়েলবাউলিগ.ডে
আলফ্রেড

1
আহা! লিঙ্কটি সত্যিই ভাল। এটি পুরানো (সকেট ব্যবহার করে ...6.৩ ব্যবহার করুন)! মূলত একই ধারণা। কুকি আনুন, সেশনের দোকানে চেক করুন এবং সত্যতা দিন :)
শ্রীপাদ কৃষ্ণ

@ নাইটওয়ালফ এটি কাজ করা উচিত কারণ আপনি জাভাস্ক্রিপ্টে কুকি আনছেন ফ্ল্যাশ নয় (ক্রিয়া স্ক্রিপ্ট)। GetCookieজাভাস্ক্রিপ্ট ফাংশন।
শ্রীপদ ​​কৃষ্ণ

1
@ প্রচ্ছন্ন লিঙ্কটি এখন মারা গেছে বলে মনে হচ্ছে :(
প্র কিউ

@ আলফ্রেডের লিঙ্কটি আবার বৈধ হয়েছে 2018-02-01
টম

32

পুশর্যাপ কীভাবে ব্যক্তিগত চ্যানেলগুলি করে তাও আমার পছন্দ হয়েছিল ।এখানে চিত্র বর্ণনা লিখুন

একটি অনন্য সকেট আইডি উত্পন্ন এবং পুশার দ্বারা ব্রাউজারে প্রেরণ করা হয়। এটি AJAX অনুরোধের মাধ্যমে আপনার অ্যাপ্লিকেশনকে (1) প্রেরণ করা হয়েছে যা ব্যবহারকারীকে আপনার বিদ্যমান প্রমাণীকরণ সিস্টেমের বিরুদ্ধে চ্যানেলটি অ্যাক্সেস করার অনুমতি দেয়। যদি সফল হয় তবে আপনার অ্যাপ্লিকেশনটি আপনার সাথে স্বাক্ষরিত ব্রাশকে একটি অনুমোদনের স্ট্রিং ফেরার গোপনীয়তা ফেরত দেয়। এটি ওয়েবসকেটের উপর দিয়ে পুশারে প্রেরণ করা হয়েছে, যা অনুমোদনের স্ট্রিং মেলে যদি অনুমোদনের (2) সম্পূর্ণ করে।

কারণ socket.ioপ্রতিটি সকেটের জন্য অনন্য সকেট_আইডিও রয়েছে।

socket.on('connect', function() {
        console.log(socket.transport.sessionid);
});

তারা ব্যবহারকারীদের অনুমোদনের জন্য স্বাক্ষরিত অনুমোদনের স্ট্রিং ব্যবহার করেছিল ।

আমি এটি এখনও মিরর করা হয়নি socket.io, তবে আমি মনে করি এটি বেশ আকর্ষণীয় ধারণা হতে পারে।


3
এটা সত্যিই দারুন. তবে আপনার অ্যাপ্লিকেশন সার্ভার এবং ওয়েবসকেট সার্ভারটি পৃথক না করা থাকলে কেবল কুকি ব্যবহার করা সহজ be তবে আপনি সাধারণত দুটি আলাদা করতে চান (পৃথক হলে সকেট সার্ভারটি স্কেল করা সহজ হবে)। সুতরাং এটি বেশ ভাল :)
শ্রীপদ ​​কৃষ্ণ

1
@ শ্রীপাদ আপনি সম্পূর্ণ সত্য এবং আমি আপনার বাস্তবায়নটিও সত্যই পছন্দ করি: পি
আলফ্রেড

27

আমি জানি এটি কিছুটা পুরানো, তবে ভবিষ্যতের পাঠকদের জন্য কুকি পার্স করার পদ্ধতির পাশাপাশি স্টোরেজ থেকে সেশনটি পুনরুদ্ধার করা (যেমন পাসপোর্ট.সোকটিও ) আপনি টোকেন ভিত্তিক পদ্ধতির বিষয়টিও বিবেচনা করতে পারেন।

এই উদাহরণে আমি JSON ওয়েব টোকেন ব্যবহার করি যা বেশ মানক pretty আপনাকে ক্লায়েন্ট পৃষ্ঠায় টোকেন দিতে হবে, উদাহরণস্বরূপ এমন একটি প্রমাণীকরণের শেষ পয়েন্ট কল্পনা করুন যা জেডাব্লুটিটি ফেরত:

var jwt = require('jsonwebtoken');
// other requires

app.post('/login', function (req, res) {

  // TODO: validate the actual user user
  var profile = {
    first_name: 'John',
    last_name: 'Doe',
    email: 'john@doe.com',
    id: 123
  };

  // we are sending the profile in the token
  var token = jwt.sign(profile, jwtSecret, { expiresInMinutes: 60*5 });

  res.json({token: token});
});

এখন, আপনার সকেট.আইও সার্ভারটি নীচে কনফিগার করা যেতে পারে:

var socketioJwt = require('socketio-jwt');

var sio = socketIo.listen(server);

sio.set('authorization', socketioJwt.authorize({
  secret: jwtSecret,
  handshake: true
}));

sio.sockets
  .on('connection', function (socket) {
     console.log(socket.handshake.decoded_token.email, 'has joined');
     //socket.on('event');
  });

সকেট.ইও-জেভিডু মিডলওয়্যার একটি কোয়েরি স্ট্রিংয়ে টোকেনটি প্রত্যাশা করে, তাই ক্লায়েন্টের কাছ থেকে আপনি কেবল সংযোগ করার সময় এটি সংযুক্ত করতে হবে:

var socket = io.connect('', {
  query: 'token=' + token
});

আমি এখানে এই পদ্ধতি এবং কুকিজ সম্পর্কে আরও বিস্তারিত ব্যাখ্যা লিখেছি ।


হে! তাত্ক্ষণিক প্রশ্ন, আপনি ক্লায়েন্টের উপর ডিকোড করতে না পারলে কেন আপনি টোকেন দিয়ে প্রোফাইলটি পাঠাচ্ছেন?
কার্পেটফিজ

এটা হতে পারে. JWT হ'ল বেস 64, ডিজিটাল স্বাক্ষরিত। ক্লায়েন্ট এটি ডিকোড করতে পারে, তবে এটি এই উদাহরণে স্বাক্ষরটি বৈধ করতে পারে না।
হোসে এফ রোমানিলো

3

নিম্নলিখিত কাজ করার জন্য আমার চেষ্টা এখানে:

  • প্রকাশ : 4.14
  • socket.io : 1.5
  • পাসপোর্ট (সেশন ব্যবহার করে): 0.3
  • redis : 2.6 (সেশনগুলি পরিচালনা করতে সত্যই দ্রুত ডেটা কাঠামো; তবে আপনি মঙ্গোডিবি এর মতো অন্যকেও ব্যবহার করতে পারেন However তবে আমি আপনাকে ব্যবহারকারীদের মতো অন্যান্য ধ্রুবক ডেটা সংরক্ষণ করার জন্য সেশন ডেটা + মঙ্গোডিবি ব্যবহার করতে উত্সাহিত করি)

যেহেতু আপনি কিছু এপিআই অনুরোধগুলি যুক্ত করতেও পারেন তাই আমরা একই পোর্টে এইচটিটিপি এবং ওয়েব সকেট উভয়ই কাজ করতে HTTP প্যাকেজটি ব্যবহার করব ।


server.js

নিম্নলিখিত প্রযুক্তিতে কেবল পূর্ববর্তী প্রযুক্তিগুলি সেট আপ করার জন্য আপনার প্রয়োজনীয় সমস্ত কিছুই অন্তর্ভুক্ত রয়েছে। আমি এখানে আমার প্রকল্পগুলির মধ্যে একটিতে ব্যবহৃত সার্ভার.জেএস সংস্করণটি দেখতে পাচ্ছি ।

import http from 'http';
import express from 'express';
import passport from 'passport';
import { createClient as createRedisClient } from 'redis';
import connectRedis from 'connect-redis';
import Socketio from 'socket.io';

// Your own socket handler file, it's optional. Explained below.
import socketConnectionHandler from './sockets'; 

// Configuration about your Redis session data structure.
const redisClient = createRedisClient();
const RedisStore = connectRedis(Session);
const dbSession = new RedisStore({
  client: redisClient,
  host: 'localhost',
  port: 27017,
  prefix: 'stackoverflow_',
  disableTTL: true
});

// Let's configure Express to use our Redis storage to handle
// sessions as well. You'll probably want Express to handle your 
// sessions as well and share the same storage as your socket.io 
// does (i.e. for handling AJAX logins).
const session = Session({
  resave: true,
  saveUninitialized: true,
  key: 'SID', // this will be used for the session cookie identifier
  secret: 'secret key',
  store: dbSession
});
app.use(session);

// Let's initialize passport by using their middlewares, which do 
//everything pretty much automatically. (you have to configure login
// / register strategies on your own though (see reference 1)
app.use(passport.initialize());
app.use(passport.session());

// Socket.IO
const io = Socketio(server);
io.use((socket, next) => {
  session(socket.handshake, {}, next);
});
io.on('connection', socketConnectionHandler); 
// socket.io is ready; remember that ^this^ variable is just the 
// name that we gave to our own socket.io handler file (explained 
// just after this).

// Start server. This will start both socket.io and our optional 
// AJAX API in the given port.
const port = 3000; // Move this onto an environment variable, 
                   // it'll look more professional.
server.listen(port);
console.info(`🌐  API listening on port ${port}`);
console.info(`🗲 Socket listening on port ${port}`);

সকেট / index.js

আমাদের socketConnectionHandler, আমি কেবল সার্ভার.জেএস এর ভিতরে সমস্ত কিছু স্থাপন পছন্দ করি না (যদিও আপনি নিখুঁতভাবে পারতেন), বিশেষত যেহেতু এই ফাইলটি বেশ দ্রুত প্রচুর কোড ধারণ করে শেষ করতে পারে।

export default function connectionHandler(socket) {
  const userId = socket.handshake.session.passport &&
                 socket.handshake.session.passport.user; 
  // If the user is not logged in, you might find ^this^ 
  // socket.handshake.session.passport variable undefined.

  // Give the user a warm welcome.
  console.info(`⚡︎ New connection: ${userId}`);
  socket.emit('Grettings', `Grettings ${userId}`);

  // Handle disconnection.
  socket.on('disconnect', () => {
    if (process.env.NODE_ENV !== 'production') {
      console.info(`⚡︎ Disconnection: ${userId}`);
    }
  });
}

অতিরিক্ত উপাদান (ক্লায়েন্ট):

জাভাস্ক্রিপ্ট সকেট.আইও ক্লায়েন্ট কী হতে পারে তার একটি খুব প্রাথমিক সংস্করণ:

import io from 'socket.io-client';

const socketPath = '/socket.io'; // <- Default path.
                                 // But you could configure your server
                                // to something like /api/socket.io

const socket = io.connect('localhost:3000', { path: socketPath });
socket.on('connect', () => {
  console.info('Connected');
  socket.on('Grettings', (data) => {
    console.info(`Server gretting: ${data}`);
  });
});
socket.on('connect_error', (error) => {
  console.error(`Connection error: ${error}`);
});

তথ্যসূত্র:

আমি কেবল কোডের অভ্যন্তরে উল্লেখ করতে পারি নি, তাই আমি এটি এখানে সরিয়ে নিয়েছি।

1: কীভাবে আপনার পাসপোর্ট কৌশল সেট আপ করবেন: https://scotch.io/tutorials/easy-node-authentication-setup-and-local#handling- সাইনআপ নিবন্ধকরণ


2

এই নিবন্ধটি ( http://simplapi.wordpress.com/2012/04/13/php-and-node-js-session-share-redi/ ) দেখায় কিভাবে

  • রেডিসে HTTP সার্ভারের স্টোর সেশনগুলি (প্রেডিস ব্যবহার করে)
  • রেডিস থেকে নড.জেজে এই সেশনগুলি একটি কুকিতে প্রেরণ করা সেশন আইডি দ্বারা পান

এই কোডটি ব্যবহার করে আপনি এগুলি সকেট.ওতে পেতে সক্ষম হন।

var io = require('socket.io').listen(8081);
var cookie = require('cookie');
var redis = require('redis'), client = redis.createClient();
io.sockets.on('connection', function (socket) {
    var cookies = cookie.parse(socket.handshake.headers['cookie']);
    console.log(cookies.PHPSESSID);
    client.get('sessions/' + cookies.PHPSESSID, function(err, reply) {
        console.log(JSON.parse(reply));
    });
});

2

সেশন এবং সি / সের মধ্যে redis ব্যবহার করুন

// সার্ভার সাইড

io.use(function(socket, next) {
 console.log(socket.handshake.headers.cookie); // get here session id and match from redis session data
 next();
});

দেখে মনে হচ্ছে আপনি যদি আপনার নোড.জেএস শেষ পয়েন্টগুলি বৈধ করার জন্য কেবল একই কোডটি প্লাগ ইন করেন তবে (তবে আপনি যে অনুরোধের অনুরোধটি পরিচালনা করছেন তার কোনও অংশই আপনাকে মুছে ফেলতে হবে) আপনি কেবল আপনার রুটের জন্য টোকেনটি পুনরায় ব্যবহার করতে পারেন could
নিক পাইনেদা

-5

এটি করা উচিত

//server side

io.sockets.on('connection', function (con) {
  console.log(con.id)
})

//client side

var io = io.connect('http://...')

console.log(io.sessionid)

1
io.sket.sessionid আমার ক্ষেত্রে
ZiTAL

8
এটি কোনও উত্তরের চেষ্টাও নয়। এটি প্রমাণীকরণ নয় এটি কেবল একটি সংযোগ তৈরি করছে।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.