/persona-node-client

This is a node client library for Persona supporting generation, validation and caching of Oauth Tokens

Primary LanguageJavaScript

Build Status Dependency Status

Node Client for Persona, responsible for retrieving, generating, caching and validating OAuth Tokens.

Getting Started

Install the module by adding the following line to packages.json:

    "persona_client": "git://github.com/talis/persona-node-client.git#1.3.0"

Create a persona client as follows. the only required param is the user agent of your calling app/script:

var persona = require('persona_client');
var personaClient = persona.createClient('myapp/0.0.1');

optionally, you can pass some configuration in a second parameter:

var persona = require('persona_client');
var personaClient = persona.createClient('myapp/0.0.1',{
 persona_host: "users.talis.com",
 persona_port = 443,
 persona_scheme = 'https';
 persona_oauth_route = '/oauth/tokens/',
 enable_debug : true,
 logger: myCustomAppLoggerInstance,
 cache: cacheConfig, // see Caching OAuth tokens below...
 cert_background_refresh: 'true' // refresh the public cert from persona
 cert_timeout_sec: '600' // the timeout after which the obtained cert should not be used
});

If using express, we recommend the following middleware:

app.use(function(req,res,next){
    req.personaClient = personaClient;
    next();
});

Documentation

Validating tokens

Here we validate the token supplied using a specific scope (optional)

    /**
     * Check if a user is allowed to impersonate another, and logs it
     */
    app.post('/some/route', function(req,res) {
        req.param.scope = "some_scope";
        req.personaClient.validateHTTPBearerToken(req,res, function(){
           // you're good, do stuff
        });
    });

If the validation fails, 401 will be returned to the client automatically.

Pre-signing signing urls

This functionality is deprecated since 3.0.0. It will be removed in 4.0.0.

Signing:

  personaClient.presignUrl('http://url.to.sign/','mySecret',secsSinceEpocToExpiry,function(err,signedUrl) {
    // do stuff
  }

Checking:

  var isValid = personaClient.isPresignedUrlValid('http://url.to.sign/?signature=34234545','mySecret');

Client authorizations

Requesting:

  personaClient.requestAuthorization({guid: 'user_guid', title:'Required for access to admin', id:'client_id', secret:'client_secret'}, function(err,authorization) {
    // do stuff
  });

Deleting:

  personaClient.deleteAuthorization({guid:'user_guid', authorizationClientId:'auth_client_id', id:'client_id', secret:'client_secret'}, function(err) {
    // do stuff
  });

Getting a user profile

Via guid:

  personaClient.getProfileByGuid({guid:'user_guid', token:'token'}, function(err, user) {
    // do stuff
    var profile = user.profile;
  });

Updating a user profile

  personaClient.updateProfile({guid:'user_guid', profile:{first_name:'Max',surname:'Payne'}, token:'token'}, function(err, user) {
    // do stuff
    var profile = user.profile;
  });

Caching

Persona client allows multiple strategies to cache (to avoid repeated requests to Persona) via cache-service

Currently requests for the public key (to verify JWT tokens) and repeated calls to obtain token are cached.

This is configured through the persona client config, e.g.:

{
    persona_host:"localhost",
    persona_port:443,
    persona_scheme:"https",
    persona_oauth_route:"/oauth/tokens",
    cache: {
      module: "redis",
      options: {
        redisData: {
          hostname: "localhost",
          port: 6379
        }
      }
    },
    enable_debug: true,
    logger: AppLogger

module corresponds to any cache-service module: e.g. "redis" would require cache-service-redis. By default, it will use an in-memory cache (node-cache).

options are passed directly to the cache-service-{module} constructor, so can be whatever is valid for a given cache-service module.

X-Request-Id

See https://blog.viaduct.io/x-request-id/

For request tracking purposes you can optionally pass an X-Request-Id to every function call just before the callback. This is useful in a support scenario as it allows Talis to identify your requests.

Best practice is to use a new X-Request-Id for every user request passing through your system.

Example:

  var xRequestId = "SOME_RANDOMLY_GENERATED_STRING"
  log.info("Calling persona with X-Request-Id: "+xRequestId; // use this log line later if there is a problem in any support requests
  personaClient.getProfileByGuid ('user_guid', 'token', xRequestId, function(err, user) {
    // do stuff
    var profile = user.profile;
  });

Contributing

In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.

Release History

See the releases page.

License

Copyright (c) 2016 Talis Education Limited.