本文介绍了为restify.js实现基于令牌的身份验证的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用restify.js构建RESTful api,但是我不想向所有人公开该api.我将使用基于令牌的身份验证.我的想法是这样的,我不确定这是否合理.

I'm trying to build a RESTful api with restify.js, but I don't want to expose the api to everyone. And I'm going to use token-based authentication. The process in my mind is like this, I'm not sure whether it is reasonable.

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

  1. the user send username/password to an api to acquire the token.

此令牌应包含在其他所有api的调用请求中.

this token should be included in the request for the calls of every other api.

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

If this is reasonable, is there any node.js library I can use?

此外,如何保护令牌?如果有人使用令牌拦截了http请求,那么该人将获得api网址和令牌.然后,他可以根据需要发送请求.有办法避免这种情况吗?

In addition, how do I protect the token? If someone intercept a http request with the token, then that person will get the api url and the token. Then he can send request as he wants. Is there a way to avoid this?

非常感谢!

推荐答案

基本访问身份验证

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

Restify is bundled with an authorizationParser plugin. authorizationParser parser out the Authorization. When the plugin is in use, it will make req.username and req.authorization properties available. Format of the latter is:

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

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

Your server will need to selectively intercept the requests that require authentication and validate user access credentials.

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

Here is an example server that will require authentication for all calls:

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:

The easiest way to test is using 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 ,它支持基本身份验证,例如

Restify comes with inbuilt JsonClient that supports basic authentication, e.g.

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

如果您喜欢令牌身份验证,则可以使用实现身份验证流程,这是您要遵循的.

If you prefer the token authentication, then you can use restify-oauth2 package that implements Client Credentials authentication flow, which is what you are after.

文档页面逐步介绍了如何设置这种身份验证,包括每个端点的角色,并且有一个在其存储库中.

The documentation page describes step-by-step how to setup such authentication, including roles of each endpoint, and there is a code example in their repository.

摘要

无论选择哪种身份验证方法,所有这些都要求您使用HTTPS.区别在于,如果用户名/密码遭到破坏,则用户需要更改其凭据.如果令牌被泄露,则用户将需要请求一个新令牌.后者可以通过编程方式完成,而前者通常依赖于硬编码值.

Regardless of which method of authentication you choose, all of them require you to use HTTPS. The difference is that if username/password is compromised, user would need to change their credentials. If token is compromised, then user would need to request a new token. The latter can be done programmatically, while the former usually relies on hardcoded values.

旁注.在生产中,如果通过不安全的渠道(例如,不安全的渠道)至少传输了一次凭据,则必须将其视为已损坏".像SSL错误一样破坏了HTTPS,例如 Heartbleed .

Side note. In production, credentials must be considered "compromised" if transferred at least once over an insecure channel, e.g. compromised HTTPS, as in case of SSL bug, such as Heartbleed.

这篇关于为restify.js实现基于令牌的身份验证的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 18:19