2013-05-15 54 views
6

我如何使用Node.js和session.socket.io的最新版本,這是我如何設置會話(請注意,我沒有使用HTTPS連接,因此沒有secure: true):使用node.js和session.socket.io進行安全認證?

app.configure(function() { 
    app.use(cookieParser); 
    app.use(express.session({ 
     signed: true, 
     store: sessionStore, 
     secret: 'SECRET', 
     cookie: { 
      maxAge: 24 * 60 * 60 * 1000, 
      httpOnly: true 
     } 
    })); 
}); 
var sessionSockets = new SessionSockets(io, sessionStore, cookieParser); 

// Later 
sessionSockets.on('connection', function(error, socket, session) { 
    // session could be used here to detect if user is logged in 

    // e.g. login: session.name = 'x'; session.save(); 
    // e.g. checkIfLoggedIn: if (session.name) return true; 
}); 

是我的代碼安全/正確或我可以如何驗證用戶是否真的登錄? 是否有可能/建議更改客戶端上cookie的sid(因爲它提到here)?

回答

11

我會建議避免重新發明輪子和使用庫,如PassportJS。有一個模塊專門用於使用PassportJS與Socket.io here(我從來沒有用過這個雖然我目前正在一個項目,我很快就需要它)。我使用過PassportJS,它非常簡單。我會推薦這個。

+0

passportJs是最好的安全認證,我的建議是一樣的passportJS – FLF

+0

如何使用socket.id作爲會話ID?它也是可行的嗎? –

+0

@HongZhou,我不知道。但我知道Passport使得身份驗證非常簡單,如果有一個使用passport和socket.io的模塊,那麼很明顯其他人已經嘗試過它,它似乎工作正常:) – kentcdodds

-3

用戶認證和會話存儲使用Passport

var express = require('express'), 
routes = require('./routes'), 
api = require('./routes/api'), 
http = require('http'), 
path = require('path'), 
mysql = require('mysql'), 
passport = require('passport'), 
LocalStrategy = require('passport-local').Strategy; 

//MySQL 

var sqlInfo = { 
    host: 'localhost', 
    user: 'root', 
    password: '', 
    database: 'dbname' 
} 


global.client = mysql.createConnection(sqlInfo); 

client.connect(); 




var app = module.exports = express(); 




/** 
* Configuration 
*/ 

// all environments 
app.set('port', process.env.PORT || 3000); 
app.set('views', __dirname + '/views'); 
app.set('view engine', 'jade'); 
app.use(express.logger('dev')); 
app.use(express.bodyParser()); 
app.use(express.methodOverride()); 
app.use(express.static(path.join(__dirname, 'public'))); 

app.use(express.cookieParser("secret")); 
app.use(express.session({ 
    secret: 'keyboard cat' 
})); 
app.use(passport.initialize()); 
app.use(passport.session()); 

app.use(app.router); 




passport.use(new LocalStrategy(

    function(username, password, done) { 

     return check_auth_user(username,password,done); 

    } 

    )); 


// development only 
if (app.get('env') === 'development') { 
    app.use(express.errorHandler()); 
} 

// production only 
if (app.get('env') === 'production') { 
// TODO 
} 



/** 
* routes start--------------------------------------------------------------- 
*/ 
// home page contain login form 
app.get('/home', function(reg, res){ 
    //check user session value, is logged in 
    if(req.user) 
     res.render('dash',{ 
      username: req.user['member_id']//req.user array contains serializeUser data 
     }); 
    else 
     res.render('index'); 

}); 

app.get('/logout', function(req, res){ 

    req.logout(); 
    res.redirect('/home'); 
}); 

//login form submit as post 

app.post('/login', 
    passport.authenticate('local', { 
     successRedirect: '/dashboard', 
     failureRedirect: '/home' 
    }) 
    ); 
//to project dashboard 
app.get('/dash',routes.dash); 
//to project dashboard 
app.get('/signup',routes.signup); 
//to project dashboard 

app.get('*', routes.index); 

/** 
* routes end--------------------------------------------------------------------- 
*/ 


/** 
* Start Server 
*/ 

http.createServer(app).listen(app.get('port'), function() { 
    console.log('Express server listening on port ' + app.get('port')); 
}); 

Click for more details with example

12

我知道這有點舊,但對於未來的讀者,除了解析cookie並從存儲中檢索會話(例如,我自己的passport.socketio模塊)@kentcdodds所描述的方法之外,您可能還會考慮基於標記的方法。

在這個例子中,我使用了非常標準的JSON Web Tokens。你必須給到客戶端頁面的標記,在這個例子中想象返回JWT認證端點:

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 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: '[email protected]', 
    id: 123 
    }; 

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

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

現在,您socket.io服務器可以配置如下socket.io,智威湯遜中間件預計在查詢字符串令牌,因此從客戶端你只需要連接它連接時:

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

我寫了這個甲基更詳細的解釋od和cookies here

+0

對不起,爲什麼倒票?謝謝 –

+0

正是我在尋找:) –

+0

@JoséF.Romaniello這個例子,你還會用護照嗎? – amcdnl