2016-12-23 63 views
0

我想創建一個安全登錄。我想添加會話,但我無法弄清楚它們應該如何一起使用。如何使用express-session和express-mysql-session創建登錄端點

我有2個代碼,其中一個代碼來自express-mysql-session,另一個代碼是我編寫的並且有登錄(/ api/login)端點。

下面是我從express-mysql-session的readme.md中複製的代碼,它起作用。

var express = require('express'); 
var app = module.exports = express(); 
var session = require('express-session'); 
var MySQLStore = require('express-mysql-session')(session); 

var options = { 
    host: 'localhost', 
    port: 3306, 
    user: 'root', 
    password: 'password', 
    database: 'session_test' 
}; 

var sessionStore = new MySQLStore(options); 

app.use(session({ 
    key: 'session_cookie_name', 
    secret: 'session_cookie_secret', 
    store: sessionStore, 
    resave: true, 
    saveUninitialized: true 
})); 

這是終端上的輸出。上面的代碼運行良好,但不確定它做了什麼。我看到它使用netstat命令

tcp4  0  0 127.0.0.1.3306   127.0.0.1.52470  ESTABLISHED 
tcp4  0  0 127.0.0.1.52470  127.0.0.1.3306   ESTABLISHED 

則輸出

$ DEBUG=express-mysql-session* node index.js 
express-mysql-session:log Creating session store +0ms 
express-mysql-session:log Setting default options +2ms 
express-mysql-session:log Creating sessions database table +46ms 
express-mysql-session:log Setting expiration interval: 900000ms +42ms 
express-mysql-session:log Clearing expiration interval +0ms 

然後下面是基本的登錄身份驗證端點使用我Express創建已建立連接到本地運行MySQL。這工作,但我想補充express-sessionexpress-mysql-session以及使用crypt, bcrypt or scrypt-for-humans,但不知道如何整合它。

const express = require('express'); 
const bodyParser = require('body-parser'); 
const mysql  = require('mysql'); 
const app = express(); 
app.use(bodyParser.json());  // to support JSON-encoded bodies 
app.use(bodyParser.urlencoded({  // to support URL-encoded bodies 
    extended: true 
})); 

app.set('port', (process.env.API_PORT || 8000)); 

const connection = mysql.createConnection({ 
    host  : 'localhost', 
    user  : 'root', 
    password : 'password', 
    database : 'authdb' 
}); 

connection.connect(function(err) { 
    if (err) { 
    console.error('error connecting: ' + err.stack); 
    return; 
    } 

    console.log('connected as id ' + connection.threadId); 
}); 

app.post('/api/login', function(req, res) { 
    const user_id = req.body.user_id; 
    const password = req.body.password; 
    let response = {}; 
    res.setHeader('Content-Type', 'application/json'); 

    connection.query('SELECT password from user WHERE `username` = "' + user_id + '"' , function(err, rows) { 
    if (err) throw err; 

    if (rows.length > 0) { 
     if (password === rows[0].password) { 
     response.status = 200; 
     response.message = "authenticated"; 
     response.authenticated = true; 
     response.user_id = user_id; 
     } else { 
     response.status = 403; 
     response.message = "Login failed!"; 
     response.authenticated = false; 
     response.user_id = user_id; 
     } 
    } else { 
     response.status = 403; 
     response.message = "Login failed!"; 
     response.authenticated = false; 
     response.user_id = user_id; 
    } 
    res.status(response.status).send(JSON.stringify(response)); 

    }); 

}); 

app.listen(app.get('port'),() => { 
    console.log(`Find the server at: http://localhost:${app.get('port')}/`); 
}); 
+0

您應該搜索一些示例以及可能的更高級別的庫,以處理auth並獲得適合您的基本知識。事實上,您似乎已經擁有sqli vuln和明文密碼存儲。密碼爲 – pvg

+0

,我將使用上面提到的bcrypt。謝謝。 – devwannabe

+0

downvote有什麼用?我的主要問題與快速會話集成有關,我甚至包含代碼。 – devwannabe

回答

0

我得到了它的工作,並非常滿意的結果。我的登錄終端運行良好!我現在對如何改善它有更多的想法。這裏是REST客戶端的截圖 - http://i.imgur.com/fJOvmzh.png以下是端點

app.post('/api/login', function(req, res) { 
    const user_id = req.body.user_id; 
    const password = req.body.password; 
    let response = {}; 
    res.setHeader('Content-Type', 'application/json'); 
    connection.query('SELECT * FROM authdb.users as authusers inner join authdb.passwords as hashed on authusers.email = hashed.email WHERE authusers.email = "' + user_id + '"' , function(err, rows) { 
    if (err) throw err; 

    Promise.try(function(){ 
     return scrypt.verifyHash(password, rows[0].password); 
    }).then(function(){ 
     var sess = req.session; 
     if (sess.views) { 
      sess.views++; 
     } else { 
      sess.views = 1 
     } 
     response = { status: 200, message: "Login successful!", authenticated: true, user_id: user_id, views: sess.views } 
     res.status(response.status).send(JSON.stringify(response)); 
    }).catch(scrypt.PasswordError, function(err){ 
     response = { status: 403, message: "Login failed!", authenticated: false, user_id: user_id } 
     res.status(response.status).send(JSON.stringify(response)); 
    }); 
    }); 
}); 

,以確保安全,我會建立一個ELB後面的EC2這將終止所有的SSL連接,併發送所有流量中明確向的NodeJS運行由PM2或其他更好的平衡器產生的Express auth API。 AWS secgroup只接受來源爲ELB的流量。