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

add support for reading token from cookie #43

Merged
merged 16 commits into from Aug 29, 2022

Conversation

lallenfrancisl
Copy link
Contributor

This PR aims to fix #28 by adding two fields in settings to set the header name and cookie name. Then while reading the token instead of hardcoding the header name or cookie name we read from what is specified in the settings.

Let me know if there is any changes that should be done in the PR

Thank you

@lallenfrancisl lallenfrancisl changed the title add support for reading token from cookie fixes #28 add support for reading token from cookie resolves #28 Nov 14, 2021
@lallenfrancisl
Copy link
Contributor Author

lallenfrancisl commented Nov 14, 2021

Ouch. Ok will fix this up. Are these tests same as the local tests ?

Copy link

@kanongil kanongil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution. I'm sure it is a useful feature. However, this needs another pass including tests and docs before it can be merged.

lib/plugin.js Outdated Show resolved Hide resolved
lib/plugin.js Outdated Show resolved Hide resolved
lib/plugin.js Outdated Show resolved Hide resolved
lib/plugin.js Outdated Show resolved Hide resolved
lib/plugin.js Outdated
// authorization header as the default
const authorization =
request.headers[settings.headerName]
|| getTokenFromCookie(request.headers.cookie, settings.cookieName)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of the custom cookie header parsing. I would prefer that the existing hapi parser is used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you use the existing parser to parse the cookie header value ? Like we need to be able to read the field and its value from something like token=ejTdsfsdhfsdjfsdjfsdfs.sdfsjdflkjsldfkjsdf.sdflsjdlfjlsdf; another=gibberish, so that we get token field's value right ? Could give me some pointers on this ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also check out https://github.com/hapijs/cookie/blob/master/lib/index.js for an example of how another plugin handles cookies.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I will read these and do the changes. This was something I had some doubts about earlier, so thank you for clearing that up

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh the cookies are already parsed for us to use 😃. I didn't know that. I have done the changes and will push the changes now

lib/plugin.js Outdated
.required()
.required(),

headerName: Joi.alternatives()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally the string would be restricted to valid header names using an appropriate regex.

lib/plugin.js Outdated
.try(Joi.string(), Joi.boolean()).default('authorization').optional(),

cookieName: Joi.alternatives()
.try(Joi.string(), Joi.boolean()).default('token').optional()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally the string would be restricted to valid cookie names using an appropriate regex.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But doesn't that reduce flexibility? Also the issue author and also a lot of other people actually have a requirement to use the names that they need. Like for example if they have a refresh token and an auth token then it makes sense for them to have two cookies in which the authentication one might be better named as auth_token

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm talking about verifying that the string value is valid to include as a cookie name, eg. no spaces, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now added, now only valid cookie names and header names are accepted

lib/plugin.js Outdated
.try(Joi.string(), Joi.boolean()).default('authorization').optional(),

cookieName: Joi.alternatives()
.try(Joi.string(), Joi.boolean()).default('token').optional()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a default value? That does not seem safe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a default value for providing a sane default. Having the header named authorization and cookie named token is a common usage that's why I did that. Also it would ensure parity with the current behaviour of using the authorization header

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a breaking change, since existing implementations will suddenly also validate tokens provided in Cookie: token=<jwt>.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated this so that by default it only reads from authorization header but not from cookie

lib/plugin.js Outdated Show resolved Hide resolved
lib/plugin.js Outdated Show resolved Hide resolved
- make settings be specified in alphabetic order
- ditch using custom parser and just use the parsed tokens from the request object
- make sure everything follow the styleguide
@lallenfrancisl
Copy link
Contributor Author

I have done all the changes that I have given thumbs up. Some of the changes that you requested are no longer relevant as they were related to parsing the cookies, but rest of the thumbs upped are done

@lallenfrancisl
Copy link
Contributor Author

The checks are shown as failed because of test coverage right ?

@kanongil
Copy link

The checks are shown as failed because of test coverage right ?

Yes. Hapi requires all merged code to have 100% test coverage.

You can run the tests locally using: npm test

For more coverage details you can do npm run test-cov-html, and open the generated coverage.html file.

@lallenfrancisl
Copy link
Contributor Author

Is there something I can do about JWKS endpoint error when running the tests ?

@devinivy
Copy link
Member

devinivy commented Jul 23, 2022

@lallenfrancisl my guess is that you may have been seeing JWKS errors on node v17+. If you use node v16 to write the tests, then you shouldn't run into any JWKS errors 👍

These will be resolved in the next version of @hapi/jwt which will support node v18 (#47).

@lallenfrancisl
Copy link
Contributor Author

Oh hey @devinivy kind of forgot about this pr, I will brush this up and do the updates and also try running the tests with node v16

@lallenfrancisl
Copy link
Contributor Author

Ok the issue was that the host when running from macos is set to something else instead of localhost so that was the reason for failing tests. So I set the host to localhost explicitly on everywhere its mocked

@lallenfrancisl lallenfrancisl changed the title add support for reading token from cookie resolves #28 add support for reading token from cookie Jul 24, 2022
@lallenfrancisl
Copy link
Contributor Author

@devinivy @kanongil Updated the pr but now its not backwards compatible. I still haven't updated the tests but before that I wanted to know how you want the behavior to be, should I keep backwards compatibility or a breaking change

@devinstewart
Copy link
Member

I personally, perhaps selfishly, would like the defaults to currently work as is. I have not tested it out yet, but it looks like I will have no issues with 3.0.0 as I am currently running Node v14 and hapi v20 in CJS.

Basically, if you are sending your JWT as Authorization: Bearer <token>, (case insensitive) no changes are needed to your plugin config.

@lallenfrancisl
Copy link
Contributor Author

Ok cool, then I will make the pr like this. The default behavior will be kept. That is it will accept authorization header by default but it will not read from any cookie by default. Then if cookie name is specified it does not allow you to specify the header name and will only read from cookie name

@lallenfrancisl
Copy link
Contributor Author

@kanongil @devinivy updated the pr with unit tests, requested changes and docs

@lallenfrancisl
Copy link
Contributor Author

The lint seems to be the one failing not tests right ? Or is it some issue from my side ?

@lallenfrancisl
Copy link
Contributor Author

lallenfrancisl commented Jul 27, 2022

Ok bumped @hapi/lab version now the tests should pass

@lallenfrancisl
Copy link
Contributor Author

lallenfrancisl commented Jul 28, 2022

@kanongil @devinivy Can any one of you trigger the workflow so that I can see if the test breaking issue is fixed ?

@lallenfrancisl
Copy link
Contributor Author

@kanongil could you do the review again with all the changes that happened ?

Copy link
Member

@devinivy devinivy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me—thank you for the contribution! I just left some final touchups for consistency.

test/utils.js Outdated Show resolved Hide resolved
test/utils.js Outdated Show resolved Hide resolved
test/utils.js Outdated Show resolved Hide resolved
lib/plugin.js Outdated Show resolved Hide resolved
lib/plugin.js Outdated Show resolved Hide resolved
lib/plugin.js Outdated Show resolved Hide resolved
API.md Outdated Show resolved Hide resolved
API.md Outdated Show resolved Hide resolved
API.md Outdated Show resolved Hide resolved
@devinivy devinivy merged commit eadc1ee into hapijs:master Aug 29, 2022
@devinivy devinivy added the feature New functionality or improvement label Aug 29, 2022
@devinivy devinivy self-assigned this Aug 29, 2022
@devinivy devinivy added this to the 2.2.0 milestone Aug 29, 2022
@lallenfrancisl
Copy link
Contributor Author

Thanks @devinivy will definitely try to keep these changes next time in mind

@lallenfrancisl lallenfrancisl deleted the load-token-from-custom-headers branch August 29, 2022 21:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New functionality or improvement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Load the JWT from an arbitrary location in the request
4 participants