hapijs / hapi

The Simple, Secure Framework Developers Trust
https://hapi.dev
Other
14.61k stars 1.34k forks source link

Use parsed payload during strategy validation ? #2232

Closed hems closed 9 years ago

hems commented 9 years ago

In the implementation i'm doing i need to validate user_id / token from a payload, in order to do that i would like to access the parsed content of request.payload during my strategy in order to query my login database and forward the user credentials.

But unfortunately during that phase of the Request Cycle, request.payload is undefined.

Any workarounds? Perhaps i should be using som server extension or another module in order to implement that?

example code:

server.auth.scheme("payload_auth", function(server, options) {
  return {
    authenticate: function(request, reply) {
      var find, payload, token, user_id;
      payload = request.payload.session;
      user_id = payload.user_id;
      token = payload.token;
      find = {
        _id: user_id,
        token: token
      };
      return db.users.findOne(find, function(error, user) {
        if (error) {
          return console.log(error);
        }
        return reply(null, {
          credentials: {
            user: user
          }
        });
      });
    }
  };
});

server.auth.strategy('my_custom_auth', 'payload_auth');
hems commented 9 years ago

One hack that work when running tests is payload = JSON.parse(req._shot.payload), but that doesn't work when actually running the sever...

server.auth.scheme("payload_auth", function(server, options) {
  return {
    authenticate: function(request, reply) {
      var payload, req;
      req = request.raw.req;
      payload = JSON.parse(req._shot.payload);
      /** **/
    }
  };
});
hueniverse commented 9 years ago

Use the payload authentication step. In 8.0 you can override the route config and require payload validation in the auth scheme.

hems commented 9 years ago

Sorry, is the "payload" authentication only available at 8.0 ?

I tried to install 8.0 from master, but npm install failed:

tests/hapi8test [ npm install git://github.com/hapijs/hapi.git#master --save                                                                  ] 7:22 pm
npm ERR! Error: version not found: inert@2.0.0-rc5
npm ERR!     at /usr/local/lib/node_modules/npm/lib/cache/add-named.js:125:12
npm ERR!     at saved (/usr/local/lib/node_modules/npm/node_modules/npm-registry-client/lib/get.js:167:7)
npm ERR!     at Object.oncomplete (fs.js:107:15)
npm ERR! If you need help, you may report this *entire* log,
npm ERR! including the npm and node versions, at:
npm ERR!     <http://github.com/npm/npm/issues>

npm ERR! System Darwin 13.4.0
npm ERR! command "node" "/usr/local/bin/npm" "install" "git://github.com/hapijs/hapi.git#master" "--save"
npm ERR! cwd /Users/hems/git/tests/hapi8test
npm ERR! node -v v0.10.33
npm ERR! npm -v 1.4.28
npm ERR! not ok code 0
tests/hapi8test [
hems commented 9 years ago

Would that implementation be valid for hapi 7.x ?

// server.js
server.auth.scheme("my_custom_payload", function(server, options) {
  return {
    authenticate: function(request, reply) {
      return reply(null, {
        credentials: {
          user: {}
        }
      });
    },
    payload: function(request, reply) {

      if( false ) {
        return reply( { error: 'my_error' } );
      };

      if( true ) {
        return reply( null, {
          credentials: {
            user: user
          }
        });
      };

    },
    options: {
      payload: true
    }
  };
});

server.auth.strategy('payload', 'my_custom_payload');

// route.js
module.exports = {
    method : 'POST',
    path   : '/api/v1/settings',
    config : {
        auth: "payload"
   }
}
hueniverse commented 9 years ago

Payload auth is in 7.x but you need to manually force every route config to use it.

hems commented 9 years ago

it's OK for now... what should i add that specification to my route?

is my scheme implementd correctly with the { options: { payload: true }} and reply( null, { credentials: { user: user } } ?

i'm trying to find the correct use on the website, but i'm still a bit confused

hems commented 9 years ago

After reading the site carefully, i managed to make it ( :

Thank you :+1:

// server.js
server.auth.scheme("my_custom_scheme", function(server, options) {
  return {
    authenticate: function(request, reply) {

    // authentication doesn't anything, we just keep it
    // cause it's a required function?
      return reply(null, {
        credentials: {
          user: {}
        }
      });
    },
    payload: function(request, reply) {

        user = magic_code();

        // here we fetch the parsed payload ?
        payload = request.payload;

        if (error) {
          console.error(error);

          return reply({
            succes: false,
            error: {
              message: error,
              code: 'db_error'
            }
          });
        }

        if (user === null) {
          return reply({
            error: 'user_not_found',
            succes: false
          });
        }

        // inject use into credentials object ?
        request.auth.credentials.user = user;

        return reply();
      });
    },
    options: {
      payload: true
    }
  };
});

server.auth.strategy('payload', 'my_custom_scheme');

// route.js
module.exports = {
  method: 'POST',
  path: '/api/v1/settings',
  config: {
    auth: {
      strategies: ["payload"],
      payload: true
    }
  }
};
hueniverse commented 9 years ago

If there are ways to improve the docs, please submit a PR.

hems commented 9 years ago

I'm not sure if this example i have have done for payload validation would add something to the docs?

I guess this is 7.x related? I can't find the API Documentation for 7.x.

Also i never did the "make me hapi" tutorial, so i'm not sure if that payload validation example would go there.

Let me know, as i said i would be happy to update to 8.x ( but i did not find instructions to install that ) and help on the 8.x doc for instance adding a payload validation example or whatever other way we might find relevant.

hueniverse commented 9 years ago

I think it might be helpful to add something to the auth tutorial on hapijs.com.

hems commented 9 years ago

where is the website repo? and where is the instructions to install 8.x ?

sorry there is so many modules under hapijs/ i scrolled through and did not find the website.

hueniverse commented 9 years ago

hapijs/hapijs.com and there should be an 8.x branch.

hems commented 9 years ago

cool, i tried from master the other day did not work.

now npm install git://github.com/hapijs/hapi.git#master --save went well ( :

will have a look on the site repo now.

hems commented 9 years ago

I just added a first draft here: https://github.com/hems/hapijs.com/compare/hapijs:beta...hems:docs/payload_auth#diff-0

definitely need tweaking, please apologise my lack of experience with hapi ( :

let me know what to tweak, and i'm hapi to do it.

:+1:

hueniverse commented 9 years ago

a PR is the best way to get it reviewed.

hems commented 9 years ago

no worries