1

仍嘗試學習javascript和nodejs。我得到了一個點,我有節點服務器,它路由我的請求,回答我,查詢MySQL數據庫,我認爲工程相當好!,問題是,即時通訊需要一些方式來驗證用戶將是隻有一個能夠在db中編輯,刪除或創建記錄。使用nodejs web服務器驗證用戶,但沒有框架

這將是這樣的: 用戶1 - 瀏覽該頁面,所有選擇查詢,除了一些將增加一個訪問計數器 用戶2 - 管理員,所有強大

我已經調查,發現幾種方法這樣做,我不太瞭解他們,但他們似乎都要求我重寫幾乎所有的服務器!我用我認爲是純粹的nodejs爲它,

var http = require("http"); 
var url = require("url"); 

我也用sequelize連接到我的分貝。

調查,我發現這個: - http://passportjs.org/ 與護照的問題是,它的工作原理與快遞,我將不得不重新編寫所有

  • expressjs 再次改寫

  • http://mcavage.me/node-restify/ 而且我也發現restify,這看起來很棒,但它意味着完全重寫已經有效的東西。

  • nodejs 我似乎無法在nodejs文檔中找到有關身份驗證的內容。

我從來沒有做過認證,我不能明白,他們不涉及DB是如何工作的,我瞭解的認證:用戶登錄,並且他的要求使用具有一定訪問數據庫的用戶連接到數據庫,我知道如何做數據庫方面,但客戶端和服務器之間發生的事情,直到達到數據庫是超越我。

我會發布所有來源,隨意跳過他們,希望他們會幫助有人尋找同樣的事情。

基本上,我認爲唯一剩下的事情就是某種身份驗證以及將圖像從瀏覽器上傳到服務器並將其保存在服務器中的功能。 我將實現一個angularjs客戶端(即時通訊尚未學習),它將提出所有請求。

任何幫助將非常感激!

index.js

var server = require("./server"); 
var router = require("./router"); 
var requestHandlers = require("./requestHandlers"); 

var handle = {}; 
handle["/insertHood"] = requestHandlers.insertHood; 
handle["/selectHood"] = requestHandlers.selectHood; 


server.start(router.route, handle); 

server.js

var http = require("http"); 
var url = require("url"); //This module has utilities for URL resolution and parsing. http://nodejs.org/api/all.html#all_url 

function start(route, handle) { 
    //the web service will respond with this 
    function onRequest(request, response) { 
     var urlValues = { 
      params: {}, 
      pathName: "" 
     }; 
     var postData = ""; 

     //read the url used to call our web service 
     parseUrl(request, urlValues); 
     //console.log("path: " + urlValues.pathName); 
     //console.log("params: " + JSON.stringify(urlValues.params)); 

     //set encoding for the recieved request 
     request.setEncoding("utf8"); 

     //if post data is recieved process it here by chunks 
     request.addListener("data", function (postDataChunk) { 
      postData += postDataChunk; 
      console.log("Recieved POST data chunk '" + postDataChunk + "'."); 
     } 
     ); 

     //when we are done storing all the post data, go to the pathName 
     request.addListener("end", function() { 
      route(handle, urlValues, response, postData); 
     } 
     ); 
    } 
    http.createServer(onRequest).listen(8888); 
    console.log("Server has started"); 
} 

function parseUrl(request, urlValues) { 
    urlValues.pathName = url.parse(request.url).pathname; //parse the url pathName 
    urlValues.params = url.parse(request.url, true).query; 
} 

exports.start = start; 
exports.parseUrl = parseUrl; 

router.js

function route(handle, urlValues, response, postData) { 
    console.log("Router.js --> About to route a request for " + urlValues.pathName); 
    if (typeof handle[urlValues.pathName] === 'function') { 
     handle[urlValues.pathName](response, urlValues, postData); 
    } else { 
     response.writeHead(404, { "Content-Type": "text/plain" }); 
     response.write("404, no request handler found for " + urlValues.pathName); 
     response.end(); 
    } 
} 

exports.route = route; 

requesthandlers.js

var exec = require("child_process").exec; 
var db = require("./dataBase"); 

function insertHood(response, urlValues) { 
    urlValues.params["zoom_level"] = parseInt(urlValues.params["zoom_level"]); 
    urlValues.params["lat"] = parseFloat(urlValues.params["lat"], 10); 
    urlValues.params["lon"] = parseFloat(urlValues.params["lon"], 10); 

    console.log("requestHandler.js --> Request handler 'insertHood' was called."); 
    var result = db.execute("modify", 'INSERT INTO neighborhood (hood_location, hood_name, zoom_level) values (GeomFromText(\'POINT(:lat :lon)\'), :name, :zoom_level)', response, urlValues.params); 
} 

function selectHood(response, urlValues) { 
    console.log("requestHandler.js --> Request handler 'selectHood' was called."); 
    var result = db.execute("select", 'select x(hood_location), y(hood_location), hood_name, zoom_level from neighborhood where hood_name = :name', response, urlValues.params); 
} 

exports.insertHood = insertHood; 
exports.selectHood = selectHood; 
數據庫

。js

var Sequelize = require("sequelize"); 

//this tells sequelize how to connect to the data base 
//see http://sequelizejs.com/documentation#usage-basics 
var sequelize = new Sequelize('mydb', 'myuser', 'mypass', 
    { 
     host: "localhost", 
     port: 3306, 
     dialect: 'mysql' 
    } 
); 

/* 
Pre: 
type: a string to know if the query is a select and returns rows, or a modify query, and returns nothing 
query: an sql query in string format with the parameters :param in place 
response: a response object where the results of the query will be written 
parameters: from sequelize, an array with the parameter for the sql query in the correct order 

Pos: 
response: the object will have the results of the query, an error or the rows of the results set 
*/ 
function execute(type, query, response, parameters) { 
    console.log("Query: " + query); 
    var options = { raw: true }; 

    var result = sequelize.query(query, null, options, parameters) 
    .success(function (rows) {   
     if (type == 'select') { 
      response.writeHead(200, { "Content-Type": "application/json" }); 
      response.write(JSON.stringify(rows)); 
      response.end(); 
     } else if (type == 'modify') { 
      response.writeHead(200, { "Content-Type": "text/html" }); 
      response.write("Query was successful"); 
      response.end(); 
     } 
    } 
    ).error(function (e) { 
     console.log("An error occured: ", e); 
     response.writeHead(404, { "Content-Type": "text/html" }); 
     response.write("There was an error man, shits on fire yo ---> " + e); 
     response.end(); 
    } 
    ); 
} 

exports.execute = execute; 

回答

1

即使沒有外部框架,基本認證也不算太困難。最困難的部分實際上只是妥善維護會議。我會強烈建議您使用session這個,但它不是必要的。 Connect的會話在這裏是非常理想的,因爲它管理過期的會話,所以你沒有一個不斷增加的對象。

爲了保持身份驗證,一旦用戶輸入了他們的憑證並將它們發送到服務器,請使用有效的憑據對它們進行交叉檢查;如果它們匹配,那麼您將需要在客戶端使用唯一的UUID存儲cookie。在服務器端,保持包含所有經過身份驗證的用戶的散列的對象。這樣,只要用戶連接,服務器就可以檢查它們是否已經有cookie來證明其憑據,這樣就不必在每個頁面上登錄。

像這樣的東西應該在基本情況下工作:

路由:

var sessions = {}

if(req.headers.cookies['sid'] && sessions[req.headers.cookies['sid']]) 
    //continue 
else 
    //return login page 

用戶登錄:

if(req.query.username == someUsername && req.query.password == somePassword){ 
     res.writeHead(200, { 
      'Set-Cookie': 'sid=UUID', //will need a uuidgen here 
      'Content-Type': 'text/plain' 
     }) 
     sessions[UUID] = true //store session on server 
     return res.send(200,somePage) 
} 
+0

謝謝回答,你說給我一些想法,但仍然沒有得到一些東西,這就是我要做的事情:一旦用戶登錄將他的憑據存儲在cookie中。當他提出請求時,通過POST發送他的憑據並使用它們在數據庫上進行身份驗證。如果cookie沒有證書,那麼他沒有登錄,我應該要求他。每次發出請求時,我都會連接並從數據庫斷開連接,這可以嗎?另外,在你的例子中,你如何知道在Hash中檢查哪個憑證?你如何管理數據庫連接? – Toddy

+0

@Toddy存儲用戶憑據的客戶端通常是不安全的,並且沒有理由需要這樣做。散列的要點是它是服務器上特定用戶驗證狀態的唯一標識符。在每個請求上連接到數據庫既費時又不必要。您應該保持數據庫連接在服務器上處於打開狀態,並根據是否驗證用戶來決定是否允許讀取/寫入。 – Ari