-
Notifications
You must be signed in to change notification settings - Fork 144
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
Change session and token handling #42
Change session and token handling #42
Conversation
get isAuthenticated() { | ||
return !!this.user; | ||
} | ||
|
||
makeTokenSet(tokenSet) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This lets developers create a TokenSet
without importing the library directly.
lib/config.js
Outdated
@@ -36,6 +36,10 @@ const paramsSchema = Joi.object().keys({ | |||
loginPath: Joi.string().optional().default('/login'), | |||
logoutPath: Joi.string().optional().default('/logout'), | |||
legacySameSiteCookie: Joi.boolean().optional().default(true), | |||
sessionName: Joi.string().token().optional().default('identity'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the actual cookie name for the internal session.
lib/loadEnvs.js
Outdated
@@ -3,21 +3,14 @@ const fieldsEnvMap = { | |||
'baseURL': 'BASE_URL', | |||
'clientID': 'CLIENT_ID', | |||
'clientSecret': 'CLIENT_SECRET', | |||
'sessionSecret': 'SESSION_SECRET', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SESSION_SECRET
is the env name for the secret that encrypts the cookie. If this env exists then the config value does not need to be passed to the SDK config.
}; | ||
|
||
module.exports = function(params) { | ||
Object.keys(fieldsEnvMap).forEach(k => { | ||
if (params[k]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was treating false
as not set
}; | ||
|
||
module.exports = function(params) { | ||
Object.keys(fieldsEnvMap).forEach(k => { | ||
if (params[k]) { | ||
return; | ||
if (typeof params[k] === 'undefined') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the config key is not present then use the env var for specific keys.
}); | ||
|
||
if (!params.baseURL && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot of dancing around to allow a very specific case. Also: sets the URL without TLS.
middleware/auth.js
Outdated
req.session.openidTokens = tokenSet; | ||
req.openIdTokens = tokenSet; | ||
|
||
if (config.sessionSecret) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is a session secret, then we store the claims in a cookie.
middleware/auth.js
Outdated
if (config.sessionSecret) { | ||
let identityClaims = tokenSet.claims(); | ||
// Remove validation claims to reduce stored size. | ||
['aud', 'iss', 'exp', 'nonce', 'azp', 'auth_time'].forEach(claim => delete identityClaims[claim]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would c_hash/at_hash also be included?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gkwang - When are those properties present?
Switch to use sessionLength instead. Setting the length to 0 will indicate an ephemeral session, reducing the need for an additional key.
lib/session.js
Outdated
@@ -0,0 +1,100 @@ | |||
const { strict: assert } = require('assert'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Encryption and signing was added and reviewed here:
https://github.com/joshcanhelp/express-openid-connect/pull/1
Appending `app` to the session-realted config keys to make it more clear what they are used for.
Added a config key for the application session cookie to allow cookie options to be passed to the session cookie.
Coverage report from
|
@@ -0,0 +1,88 @@ | |||
const { strict: assert } = require('assert'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Encryption added and reviewed by security here:
https://github.com/joshcanhelp/express-openid-connect/pull/1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few questions still, none blockers.
}); | ||
``` | ||
|
||
## 5. Calling userinfo | ||
## 7. Calling userinfo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a better title to match the access token one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I struggled with a title here because you only need to call userinfo in specific cases and I'm not sure if I could shorten that down to something universally-clear in the title. I added a bit more color in the description, though.
next(); | ||
} catch(e) { | ||
next(e); | ||
} | ||
}, | ||
getUser: function(tokenSet) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we not need this now? The descriptive text indicates we do but it looks like line 221 is mapping claims directly now. One of these seems out of step with the other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. That example was not working properly with this new system.
@damieng - Last change blew away your approval. Ready again! |
Description
This is a major breaking change to functionality. Please read the below along with the EXAMPLES.md document for how to handle your application's use case.
This PR remove the requirement for a session middleware and, instead, stores the user identity in an encrypted and signed cookie. This PR will also remove automatic storage of the
TokenSet
received from the authorization server.See API.md in this PR for added configuration options and EXAMPLES.md in this PR for how to handle token storage and user sessions with server-side sessions.
Breaking Changes:
TokenSet
is not longer stored automaticallyreq.openid.tokens
setter and gettergetUser
function to pull from configuredreq
property rather thanreq.session
References
Testing
Checklist
master