What is the best way to implement a token-based authentication for restify.js?

后端 未结 1 1107
悲哀的现实
悲哀的现实 2021-02-19 18:24

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

1条回答
  •  一整个雨季
    2021-02-19 18:55

    Basic access authentication

    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: ,
      credentials: ,
      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);
    

    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 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.

    Summary

    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.

    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.

    0 讨论(0)
提交回复
热议问题