node.js - 为 restify.js 实现基于 token 的身份验证的最佳方法是什么?

标签 node.js authentication restful-authentication restify

我正在尝试使用 restify.js 构建一个 RESTful api,但我不想将 api 公开给所有人。我将使用基于 token 的身份验证。脑子里的流程是这样的,不知道合不合理。

  1. 用户将用户名/密码发送到 api 以获取 token 。

  2. 这个 token 应该包含在所有其他 api 的调用请求中。

如果这是合理的,我可以使用任何 node.js 库吗?

另外,如何保护 token ?如果有人拦截了带有 token 的 http 请求,那么该人将获得 api url 和 token 。然后他可以根据需要发送请求。有没有办法避免这种情况?

非常感谢!

最佳答案

Basic access authentication

Restify 与 authorizationParser 插件捆绑在一起。 authorizationParser 解析出Authorization。当插件在使用时,它会使 req.usernamereq.authorization 属性可用。后者的格式为:

{
  scheme: <Basic|Signature|...>,
  credentials: <Undecoded value of header>,
  basic: {
    username: $user
    password: $password
  }
}

您的服务器将需要选择性地拦截需要身份验证的请求并验证用户访问凭据。

这是一个示例服务器,它要求对所有调用进行身份验证:

var restify = require('restify'),
    server;

server = restify.createServer();

server.use(restify.authorizationParser());

server.use(function (req, res, next) {
    var users;

    // if (/* some condition determining whether the resource requires authentication */) {
    //    return next();
    // }

    users = {
        foo: {
            id: 1,
            password: 'bar'
        }
    };

    // Ensure that user is not anonymous; and
    // That user exists; and
    // That user password matches the record in the database.
    if (req.username == 'anonymous' || !users[req.username] || req.authorization.basic.password !== users[req.username].password) {
        // Respond with { code: 'NotAuthorized', message: '' }
        next(new restify.NotAuthorizedError());
    } else {
        next();
    }

    next();
});

server.get('/ping', function (req, res, next) {
    res.send('pong');

    next();
});

server.listen(8080);

最简单的测试方法是使用 curl:

$ curl -isu foo:bar http://127.0.0.1:8080/ping

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 6
Date: Fri, 12 Dec 2014 10:52:17 GMT
Connection: keep-alive

"pong"

$ curl -isu foo:baz http://127.0.0.1:8080/ping

HTTP/1.1 403 Forbidden
Content-Type: application/json
Content-Length: 37
Date: Fri, 12 Dec 2014 10:52:31 GMT
Connection: keep-alive

{"code":"NotAuthorized","message":""}

Restify 内置了 JsonClient支持基本身份验证,例如

var restify = require('restify'),
    client;

client = restify.createJsonClient({
    url: 'http://127.0.0.1:8080'
});

client.basicAuth('foo', 'bar');

client.get('/ping', function(err, req, res, obj) {
    console.log(obj);
});

OAuth 2.0

如果您更喜欢 token 认证,那么您可以使用 restify-oauth2实现 Client Credentials 的包身份验证流程,这就是您所追求的。

文档页面逐步描述了如何设置此类身份验证,包括每个端点的角色,并且有一个 code example在他们的存储库中。

总结

无论您选择哪种身份验证方法,它们都要求您使用 HTTPS。不同之处在于,如果用户名/密码被泄露,用户将需要更改其凭据。如果 token 被泄露,则用户将需要请求新 token 。后者可以通过编程方式完成,而前者通常依赖于硬编码值。

旁注。在生产中,如果通过不安全的 channel (例如HTTPS 受损,如 SSL 错误,例如 Heartbleed .

关于node.js - 为 restify.js 实现基于 token 的身份验证的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18411946/

相关文章:

node.js - 如何将 C++/Javascript Node.js 组合插件的代码覆盖率发布到 Coveralls.io?

authentication - 为什么在 Google API 中对网络应用程序使用 ClientLogin 是一个坏主意?

rest - SharePoint 本地 2013 REST 身份验证

node.js - PG/Node.js 的 Heroku h12 超时错误

node.js - npm 警告 : npm does not support Node. js v12.4.0

Node.js - 使用 Promise.all() 加载并执行多个函数

ruby-on-rails - 使用子域在 rails 2.3.2 应用程序中丢失 session

javascript - 根据用户状态显示/隐藏登录/注销按钮

正则表达式和 POST 在同一连接中

web-services - 为 iOS/Android 应用程序保护基于 REST 的服务的选项