Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Obtain the request token in the handler #123

Closed
mcortesi opened this issue Nov 16, 2015 · 13 comments
Closed

Obtain the request token in the handler #123

mcortesi opened this issue Nov 16, 2015 · 13 comments

Comments

@mcortesi
Copy link
Contributor

It's really a question, don't know if it's the right place to ask it.

I need to obtain the user token within a route handler. It's useful to me, since i can use it to proxy call to other servers using the user's authentication token.

I checked the code and I've notice it's not stored anywhere. So, I ended up creating a onPostAuth listener that calls the extract() function from the module, with the same options that i used for the plugin.

Do you image any other way of doing it? Does it seem a good thing to add to the library? If so, I have no problem in adding it so, and sending a pull request.

@nelsonic
Copy link
Member

hi @mcortesi,
actually, the result object must have a credentials property so the decoded token is always available in any route that required JWT2 Auth... let me know if you need help. 👍

@mcortesi
Copy link
Contributor Author

Thanks @nelsonic for the quick reply.
I was referring to the unverified token, not to the decoded one. The server can't sign a new token, so it need to use the one the user has.

Optionally it could have it's own token, but that's another story.

The value I want is the one here: https://github.com/dwyl/hapi-auth-jwt2/blob/master/lib/index.js#L29

@nelsonic
Copy link
Member

Ah, yes, if you need the token before its decoded/verified then you would need to extract it as you have done. 👍
May I ask: are you performing additional checks on the encoded token in your code?

@mcortesi
Copy link
Contributor Author

I use the plugin for that.
The use case, is to have something that works as proxy server. It validates the token authenticity and use it to generate other requests to other servers.

So, I need to decode and verify the signature of the token; but i also need the token to call other servers. So in some way, we are saying that we want to make a call 'on behalf of' the user making the request.

Is it a strange or ill advised use case?

@nelsonic
Copy link
Member

That sounds fine. Proxying the "other" server makes sense.
The only thing I would say is if you re-using the same JWT for the querying the next service,
are you ok with the possibility that your end-user (or an attacker) could issue the same request to the "other" servers?

@mcortesi
Copy link
Contributor Author

Initially yes. But our idea is to device an on behalf of mechanism probably using two jwt, one of the server's and one for the user.

Going back to my first comment, does it make sense to expose the token in the plugin?
Something like request.plugins['hapi-auth-jwt2'].token?

@nelsonic
Copy link
Member

Good question. exposing the raw JWT is not something we had considered ... but it sounds like a legit use-case which other people will have. if you have time, please send us a Pull Request exposing the extract method.

@mcortesi
Copy link
Contributor Author

@nelsonic will do.

Now, about that.

To extract method expects an options parameter that we already set on the strategy. So we need to replicate that call.

My suggestion would be set the token in the request. Where? I'm not to sure, since there seem to be some possible places for that:

  1. Use request.auth.artifacts.token. Artifacts since to be the place where an auth scheme/strategy can leave it's stuff for authentication issues.
  2. Use request.auth.token. It's the nicest path in my opinion, but seems to be creating a new property that is not expected by hapi. At the same time, I was browsing the cookie scheme earlier, and they create auth.session, so why shouldn't us?
  3. Use request.plugins['hapi-auth-jwt2'].token. It's what hapi documentation describes as the place for plugins to put request data. But also it seems to be a really ugly path to use within your handlers.

Another option is to expose an extract method with options already configured, by using a hapi decoration. But that means we can only register the plugin one, and it seems too much a limitation.

What do you think?

@nelsonic
Copy link
Member

@mcortesi this has been available in the plugin for the past few releases so I'm closing the issue. 👍

@framerate
Copy link

Is this still valid?

console.debug([TOKEN] - ${JSON.stringify(Object.keys(request.auth), null, 2)})

[TOKEN] - [
  "isAuthenticated",
  "isAuthorized",
  "credentials",
  "artifacts",
  "strategy",
  "mode",
  "error",
  "isInjected"
]

@nelsonic could be my user error, but I'm debugging :(

@nelsonic
Copy link
Member

nelsonic commented Aug 7, 2019

Hi @framerate, you're working late ... 😉

This question does not appear to be related to the OP "Obtain request token in handler ..." 😕
Always a good idea to open a fresh question (issue).

Those Object.keys seem reasonable.
If in doubt, simply run (and play with) the tests on your localhost:

git clone https://github.com/dwyl/hapi-auth-jwt2.git
cd hapi-auth-jwt2
npm install
npm test

Then open the test/basic_server.js file in your editor
and edit the privado function

const privado = function(req, h) {

e.g:

const privado = function(req, h) {
  console.log(JSON.stringify(Object.keys(req.auth).sort(), null, 2))
  return 'worked';
};

The output is:

[
  "artifacts",
  "credentials",
  "error",
  "isAuthenticated",
  "isAuthorized",
  "mode",
  "strategy",
  "token"
]

Pretty close, but no isInjected key.

Hope you are able to achieve your goal, if not please open a new GitHub issue.
Thanks.

@framerate
Copy link

Always working :)

I think maybe we got our wires crossed. it's definitely related to this bug, I'm saying that request.auth.token (like originally requested here, and listed in the documentation) is undefined in "request.auth"

That doesn't seem right?

@nelsonic
Copy link
Member

nelsonic commented Aug 7, 2019

@framerate If you console.log(req.auth) you should see:

{ 
  isAuthenticated: true,
  isAuthorized: false,
  credentials: { id: 123, name: 'Charlie', iat: 1565166536 },
  artifacts:
  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIzLCJuYW1lIjoiQ2hhcmxpZSIsImlhdCI6MTU2NTE2NjUzNn0.EjSw-Sf2N5nQTSkoIVdLsHRyAj_sVMFMrhuk77D7yIY',
  strategy: 'jwt',
  mode: 'try',
  error: null,
  token:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIzLCJuYW1lIjoiQ2hhcmxpZSIsImlhdCI6MTU2NTE2NjUzNn0.EjSw-Sf2N5nQTSkoIVdLsHRyAj_sVMFMrhuk77D7yIY' 
}

The token is the JWT.
How is it undefined? 😕

(apologies if I'm not understanding your question ... but request.auth.token is defined in our tests ...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants