2

仍在尝试学习javascript和nodejs。我到了在节点中有一个服务器的地步,它路由我的请求,回答我,查询 mysql 数据库,我认为效果很好!问题是,我需要一些方法来验证将成为只有一个能够在数据库中编辑、删除或创建记录。

它会是这样的: User1 - 浏览页面,所有选择查询,除了一些会增加访问计数器 User2 - 管理员,功能强大

我调查并发现了几种方法,我不太了解它们,但它们似乎都需要我重写几乎所有的服务器!我使用了我认为是纯 nodejs 的东西,

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

我还使用 sequelize 连接到我的数据库。

调查我发现: - http://passportjs.org/ 护照的问题是它适用于快递,我将不得不重写所有

  • expressjs 再次重写

  • http://mcavage.me/node-restify/ 我还发现了restify,它看起来很棒,但这意味着完全重写已经工作的东西。

  • nodejs 我似乎无法在 nodejs 文档中找到有关身份验证的内容。

我从未做过身份验证,如果不涉及数据库,我无法理解它们是如何工作的,我理解的身份验证是:用户登录,他的请求使用具有特定访问权限的 db 用户连接到数据库,我知道该怎么做db 端,但是客户端和服务器之间在到达 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);

服务器.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;

路由器.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;

请求处理程序.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;
4

1 回答 1

4

即使没有外部框架,基本身份验证也不会太难。最困难的部分实际上只是正确维护会话。我强烈建议您为此使用会话,但这不是必需的。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)
}
于 2013-10-17T03:28:11.150 回答