johnbrett / hapi-auth-bearer-token

Simple Bearer authentication scheme plugin for hapi, accepts token by Header, Cookie or Query parameter.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error: Unknown authentication strategy

technowar opened this issue · comments

I am trying to use this module to enable bearer token on my app. However, I am getting the error shown in the title.

I have been stuck for days now. Hoping anyone could help me.

I have user.js route

module.exports = [{
    'method' : 'GET',
    'path' : '/v1/users',
    'config' : {
        'handler' : function (request, reply) {
            User.find(function (error, data) {
                if (!error) {
                    reply(data)
                        .code(200)
                }
            });
        },
        'auth' : 'simple'
    }
}];

Now, inside my server.js,

Server.register([{
    'register' : require('hapi-auth-bearer-token')
}, {
    'register' : require('./api')
}], function (error) {
    if (!error) {
        Server.auth.strategy('simple', 'bearer-access-token', {
            'validateFunc' : function (token, callback) {
                if (token === "1234") {
                    callback(null, true, {
                        'token' : token
                    })
                } else {
                    callback(null, false, {
                        'token' : token
                    })
                }
            }
        });

        Server.start(function () {
            console.log('info', 'Server running at ' + Server.info.uri);
        });
    }
});

But I get Error: Unknown authentication strategy: simple in path: /v1/users

Complete error message:

    at Object.exports.assert (/var/nodevagrant/project/Interest/node_modules/hapi/node_modules/hoek/lib/index.js:663:11)
    at /var/nodevagrant/project/Interest/node_modules/hapi/lib/auth.js:139:14
    at Array.forEach (native)
    at internals.Auth._setupRoute (/var/nodevagrant/project/Interest/node_modules/hapi/lib/auth.js:136:24)
    at new module.exports.internals.Route (/var/nodevagrant/project/Interest/node_modules/hapi/lib/route.js:131:47)
    at internals.Connection._addRoute (/var/nodevagrant/project/Interest/node_modules/hapi/lib/connection.js:342:17)
    at internals.Connection._route (/var/nodevagrant/project/Interest/node_modules/hapi/lib/connection.js:334:18)
    at internals.Plugin._apply (/var/nodevagrant/project/Interest/node_modules/hapi/lib/plugin.js:432:14)
    at internals.Plugin.route (/var/nodevagrant/project/Interest/node_modules/hapi/lib/plugin.js:407:10)
    at Object.exports.register (/var/nodevagrant/project/Interest/api/index.js:8:9)

I figured it out.

Hi Johmel, glad you got sorted, can you post the solution so anyone else
hitting the same problem will be able to figure it out? Thank you! Any
other problems let me know.

On Thu, 22 Jan 2015 08:11 Johmel Rey Pintor notifications@github.com
wrote:

I figured it out.


Reply to this email directly or view it on GitHub
#16 (comment)
.

Instead of adding

Server.auth.strategy('simple', 'bearer-access-token', {
  'validateFunc' : function (token, callback) {
        ....
  }
});

to my server.js file, I added it to my index.js inside my /api folder.

My index.js now looks like this,

var User = require('./controllers/user');

exports.register = function (plugin, options, next) {
  plugin.auth.strategy('simple', 'bearer-access-token', {
    'validateFunc' : function (token, callback) {
        ....
    }
 });

  plugin.route(User);

  next();
};

exports.register.attributes = {
  'name' : 'api',
  'version' : 1.0
};

Ah so you were registering a route with the 'simple' auth strategy before you had actually registered the 'simple' strategy itself, very easy to do. Thanks for posting the solution to the issue.

One thing I usually do for auth in Hapi is to create a plugin called authentication which register's the auth scheme plugin - hapi-auth-bearer-token in this case, and then also registers the strategy, that way each plugin has only one concern so you don't have your api plugin also responsible for authentication.

If you want to try this pattern let me know and I can elaborate more with code samples etc.

Hey @technowar, here is an example of an authentication plugin, where you can encapsulate all auth related functionality, e.g. scheme registration, strategy function.

Registering the authentication plugin: https://github.com/johnbrett/hapi-level-sample/blob/master/index.js#L7
The auth plugin itself: https://github.com/johnbrett/hapi-level-sample/blob/master/plugins/authentication/index.js

Any questions or feedback on this approach are much welcomed, hope it helps :)

I can't figure out how to solve this issue. I'm using this hapi js boilerplate https://github.com/poeticninja/hapi-ninja from @poeticninja and I have this code:

base.js

    createOrder: {
        handler: function(request, reply) {
            (...)
            server.methods.createOrder(json, function (err, result) {
                if (err) {
                    reply(err).code(500);
                } else {
                    reply(json).code(200);
                }                
            });
        },
        validate: {
            payload: {
               (...)
            }
        },
        auth: 'simple',
        id: 'createOrder'
    },

And in plugins.js

server.register([
    {
        register: require('hapi-auth-bearer-token'),
        options: function() {
            server.auth.strategy('simple', 'bearer-access-token', {
                allowQueryToken: true,              // optional, true by default
                allowMultipleHeaders: false,        // optional, false by default
                accessTokenName: 'access_token',    // optional, 'access_token' by default
                validateFunc: function( token, callback ) {
                    // For convenience, the request object can be accessed 
                    // from `this` within validateFunc.
                    var request = this;
                    // Use a real strategy here, 
                    // comparing with a token from your database for example
                    if(token === "1234"){
                        callback(null, true, { token: token })
                    } else {
                        callback(null, false, { token: token })
                    }
                }
            });
        }
    },
    {
        register: require('hapi-mongo-models'),
        options: mongoOptions
    },
    {
        register: require("good"),
        options: goodOptions
    },
    {
        register: require("hapi-assets"),
        options: assetOptions
    },
    {
        register: require("hapi-named-routes")
    },
    {
        register: require("hapi-cache-buster")
    }
], function (err) {
    if (err) {
        console.error('Failed to load a plugin:', err);
        throw err;
    }
});

I'm getting Error: Unknown authentication strategy: simple in path: /createOrder

Hi @jgauna, the options parameter in server.register() generally expects an object of configuration properties, although I suppose you can use it for whatever you want if its your own plugin. Either way, hapi-auth-bearer-token doesn't expect the default strategy to be passed in that way, so never calls the function passed in meaning the simple strategy is never set. Is there any reason you were trying to set your authentication strategy there out of curiosity?

To fix - you need to take the server.auth.strategy() code outside of the options parameter - move it into the callback of server.register() after:

], function (err) {
    if (err) {
        console.error('Failed to load a plugin:', err);
        throw err;
    }
    // -- put the server.auth.strategy(...) code here --
});

Let me know if you've any troubles with this :)

That won't work. Here's what I did:

server.js

(...)
// Bootstrap Hapi Server Plugins
require('./server/config/plugins');

// Bootstrap Hapi Server Plugins
require('./server/config/methods');

// Bootstrap Auths
require('./server/config/auths');
(...)

auths.js

// Load the server
var settings = require('./settings'),
    server = require(settings.rootPath + '/server'),
    crypto = require('crypto'),
    md5 = require('MD5');

server.auth.strategy('simple', 'bearer-access-token', {
    allowQueryToken: true,              // optional, true by default
    allowMultipleHeaders: false,        // optional, false by default
    accessTokenName: 'access_token',    // optional, 'access_token' by default
    validateFunc: function(token, callback) {
        // For convenience, the request object can be accessed 
        // from `this` within validateFunc.
        var request = this;

        console.log("TOKEEEEN")
        console.log(token)

        console.log(request)
        // Use a real strategy here, 
        // comparing with a token from your database for example
        if (token === "1234") {
            callback(null, true, { token: token })
        } else {
            callback(null, false, { token: token })
        }
    }
});

Thanks!

I've a feeling the server variable in your auths.js is not actually a connection instance, just what is returned from Hapi.Server (presuming you are using Hapi 8 ??).

server.auth.strategy() needs to be run against an actual server connection instance (acquired by running server.connection()).

Can you attach the rest of server.js so I can see how you're passing the connection instance to auths.js?

Is this project on Github by any chance? If I could see the code and error I could diagnose this much quicker :) What error are you actually receiving also?

I figured it out. I have this working now. The only issue I have is the one I opened in:

#19

No prob @ahmad-moussawi - thanks for letting me know it was useful, makes it all the worthwhile :)

you mention: var bearerSimple= require('hapi-auth-bearer-simple')

hapi-auth-bearer-simple is a different module to this one, this is hapi-auth-bearer-token.

You're best off opening an issue on their repo: https://github.com/Salesflare/hapi-auth-bearer-simple ;)

Yeah just noticed thanks :)