tarlepp / angular-sailsjs-boilerplate

'Boilerplate' for AngularJS + Sails.js
MIT License
307 stars 87 forks source link

API Key for certain controllers #93

Closed Fyb3roptik closed 9 years ago

Fyb3roptik commented 9 years ago

Hello,

I love this thing so far! I am new to node and sails. I come from a PHP background. I want to have a site where people can login username or email/password, but I also want to give them an API key to access certain controllers for API type features. How would I go about doing this?

Thanks!

tarlepp commented 9 years ago

This one isn't directly related to "boilerplate" code, but I have some thoughs of this topic that might help you.

Some points that you need to handle

I hope this helps you.

Fyb3roptik commented 9 years ago

I am still a newb to this. Any chance I can get an example?

tarlepp commented 9 years ago

It should be really simple with policies, so learn those and make things happen first with 'static' API keys, eg. some custom header must be within request.

Fyb3roptik commented 9 years ago

Right, but their documentation is lacking. I have no knowledge of how to even get a static api key from a database column in the user table...

tarlepp commented 9 years ago

For data fetch you can use

sails.models.yourapimodel.findOne().where({key: keyToFind}).exec(function(error, result) { if (error) { // Do some error handling... } else if (!result) { // Api  key not found... } else { // Yeah record found for api key! });

And all this is found from sails docs...

Fyb3roptik commented 9 years ago

Their docs only show you 1 way of doing a policy. I have not used node much, so maybe that is it. I do not know which policy to build and for what. I read the documentation on it and am still not clear. I guess I will just keep looking. Thanks

tarlepp commented 9 years ago

And that is the way to do policies, those aren't so hard / complicated thing to do, basically those are just middleware that are run before actual controller actions. Below is an example of that API Key policy (note that I coded that "blind" just in couple of minutes), which should help you a lot.

file:

/backend/api/policies/APIKey.js

content:

'use strict';

module.exports = function APIKey(request, response, next) {
  sails.log.verbose(__filename + ':' + __line + ' [Policy.APIKey() called]');

  var apikey = '';

  if (request.headers && request.headers.authorization) {
    var parts = request.headers.authorization.split(' ');

    if (parts.length === 2) {
      var scheme = parts[0];
      var credentials = parts[1];

      if (/^Bearer$/i.test(scheme)) {
        apikey = credentials;

        sails.models.yourapikeymodel
          .findOne()
          .where({apikey: apikey})
          .exec(function(error, record) {
            if (error) {
              next(error);
            } else if (!record) {
              next('Invalid API key.');
            } else {
              sails.log.verbose('Correct API key found!');

              next();
            }
          })
      }
    } else {
      next('Invalid API key header format. Format is Authorization: Bearer [YourApiKey]');
    }
  } else {
    next('API key header not present, please provide Header Authorization: Bearer [YourApiKey]')
  }
};

This one uses the same format as the default authenticated policy, so you might need to change that example a bit. Also you need to attach this policy to routes what you want to protect. Also note that IF you need to use default authenticated and this apikey policy together, you need to create new policy with OR logic on it.

I'm closing this issue now, because all that you need is found from sails.js docs. Basically this one is just your application logic.