Ephemeral & MaxAge for express-session - express

I am trying to use the express-session package for session management in an express-js application.
I have the following requirements:
Cookie is destroyed client-side when browser is closed.
Cookie is destroyed after 15 minutes idle time.
Cookie is destroyed after 3 hours since creation (regardless of activity).
(Numbers are just examples).
I can deal with the idle time by manipulating the cookie maxAge up to a maximum. However, when I read the express-session documentation, I see:
By default cookie.maxAge is null, meaning no "expires" parameter is
set so the cookie becomes a browser-session cookie. When the user
closes the browser the cookie (and session) will be removed.
So, how do I create a "browser-session" cookie that also has a maxAge (used for idle/absolute timeout)?
I have also investigated using node-client-session package, but it does not allow for ephemeral and maxAge.

I have done an implementation of this after finding this question and wanting to have both a session timeout and ephemeral sessions. Here is what I have done to make this work in an actual application.
I use maxAge in my express-session configuration, and then in my client / web app code I hook the browser event "onbeforeunload". onbeforeunload info
It's not foolproof, and has some browser quirks, but when onbeforeunload fires, I use it to send an ajax request to the server to "logout" and kill the session.
It's important to now ask yourself what doing this does to the user experience (UX) and expected behavior of the session experience. If you want an ephemeral session, then it would be for a specific application in which you want something to be available as long as the browser is open. This could be accomplished with a short session age as well. We have to think about what the purpose of implementing this would be.

Related

Session persists error in JMeter authenticate request

In my jmeter web recording, I have an api/authenticate part which generates the token which has to be used
in subsequent requests. I did the part of correlation too. But the problem I face now is, the api/authenticate throws a session still persists error after sometime. In my script I have log out option too. In api/authenticate I am providing username and password in the headers. Since the session exists error is there, I can't get the token in the response body. Is it something that developers can fix for us? can you please help me with this? Or is there any request which is missing above this authentication part which jmeter didn't capture? I have authentication header manager added to my test plan to clear
authorization every iteration. Also cookie manager and cache manager. Nothing clears the session.
For well-behaved application "log out" request should clean the session, if it doesn't - you need to report it to your application developers.
Also check the token response, it might be the case it has some time to live and if this is the case the token persistence could be a part of your application functionality so if there is a username/password combination associated with the token you should be using it until it expires before getting the new one. So you can write the token and its expiration date into a CSV file using Flexible File Writer and use If Controller to check whether the token is still active or not

JWT Refresh token and Multi-Page Application

I am going to implement JWT authentication for several independent services.
There will be auth.example.com and service1.example.com, service2.example.com etc.
My assumptions:
JWT can be kept in cookie for ".example.com"
JWT expire time should be small (like 15 mins) because there is no reliable way to logout user with JWT token (revoke token).
Refresh tokens should be used to reissue JWT tokens
Refresh token cookies should be accessible only by auth.example.com for security reasons and because https://www.rfc-editor.org/rfc/rfc6749#section-1.5 says
"Unlike access tokens, refresh tokens are intended for use only with authorization servers and are never sent to resource servers."
Next, if I have a service - multi page application (i.e. not SPA), where some URLs are called "traditional" way, not via Ajax and render HTML
based on some server side logic, which, of course, include checking of user authorization.
then, say, there will be an action service1.example.com/user/showpage
if (user.logged_in) {
render_some_html(get_some_data(user.login))
}
else {
render_anonimous_uses_page()
}
Problem is:
If site user close all site tabs and, then after hour or so, go directly to page /user/showpage (or maybe he
suspend laptop and wake it up in an hour and go to that page).
What if by that time JWT token will expire. Then to refresh it by Refresh token we need to make Ajax call to auth.example.com (because Refresh
token is stored only in auth.example.com cookie) and this is just unaccessible in server side rendering (that pseudocode that I posted above, it's server side, and it's just impossible to make client ajax call in the middle of execution of server code. it's just not applicable here). This way user will be considered logged out
on this stage.
Redirect could be one solution.. but what if site should work for anonymous out users too, and anyway looking for something better.
This problem not exists for SPA application, because before every Ajax call to internal API, it can check JWT and make call to refresh JWT token.
And question is: is this true that JWT in general should not (cannot) be used in Multi-Page (traditional) applications because of this issue? or there is good way to workaround this? or this is not a problem at all (users don't close tabs too often, or they expect site to log them out or redirect etc)?

Is there a way to handle password changes smoothly in a CALDAV scenario without locking accounts?

i have a scenario running with an own CALDAV-server and CALDAV-clients like (iOS-calendar, mac-Calendar, Android sync adapter, Thunderbird/Lightning, Outlook Sync, ...)
The authentication so far works via basic auth (https and the "Authentication"-Header).
The CALDAV-clients store the user/password in their configuration.
So far so good, but the issue comes now once the password of the user/account either gets changed, reset, expired, etc.
The server has a restrictive password policy enforced, which locks the account after x failed attempts (e.g. 10).
What is happening now obviously is, that once the CALDAV-client configuration was not updated it continues to use an old password.
The server responds with an 401 not authorized - ok, thats fine apparently again.
But the Clients still continue to use the outdated password. It would be nicer to stop polling and present the user with a dialog that his credentials are not valid anymore. But the clients are out of my control so nothing can be directly done here.
The result: after 2-3 iterations (as most clients tries multiple request in one sync iteration) the account on the server of the user is locked due to too many failed login attempts.
That is not nice. The issue seems to be generic and known as "stale passwords".
A solution could only be a better client handling (out of scope here) or a oAuth-token handling. But i was not able to find anything that standard CALDAV-clients supports this. Only google calendar seems to enforce an oAuth2 authorization before allowing CALDAV communication.
So the question is, is there a good way to improve the bad experience of locked accounts?
Some special 401 response which tells the clients to forget the password or not using it again?
constructive feedback highly welcome.
Edit:
for macOS and ios calendar i found a strange behavior (bug) causing and/or enforcing the described situation.
A standard 401 response will cause the clients to bring up the password dialog as expected and described above. The clients stop polling until a new password is entered - as desired.
In my case the 401 response body contained an inline base 64 image (img src="data..."):
This doesnt lead to a password renewal dialog! Just a "something goes wrong" error state.
The clients are continuing to poll! Locking the accounts after some tries ;(
A solution for this problem than will be to remove the inline image but for me it sounds like a bug that an inline image in the 401 response provokes a different behavior on the client.
Some special 401 response which tells the clients to forget the password or not using it again?
Well, 401 is that response. If the client receives a 401 it knows the the login/password combination it provided doesn't work anymore, and shouldn't retry with the same. Obviously the clients don't do this, partially because:
On the other side your servers x-failed-attempts locking doesn't work with stateless protocols for obvious reasons. HTTP doesn't have that feature builtin. Locking the account is a side effect a client doesn't have to expect when running idempotent HTTP requests.
Assume the client is downloading 10 batches of items concurrently. If the credentials invalidate during this, the account would immediately be locked :-)
Summary: You can't use basic auth naively with backends that lock accounts after n-tries.
Google and iCloud both use token based auth schemes (Google OAuth, iCloud a proprietary one). You can't expect those to work in other clients. E.g. while the Apple clients support OAuth for Google, I don't think they support that for other account types.
So what can you do
I'm reading your question so that you own the account server and that the account locking is intentional and desired. (I.e. it is not a side effect of a different (e.g. SSO) backend system you reach out to.)
I think in this case it should be reasonable to rework your account system to allow unlimited login attempts with just the old password.
The lock-after-n-attempts measure is to protect against people trying different passwords. In your case it is always the same and as a bonus it also matches the old password.
There are a lot of different variations of this approach.

Desire2Learn Valence API logout

I'm trying to implement a way to actually logout from my application that is using the Valence API. I can obviously clear the session on my end, but is there a way through the API to actually log out of the Desire2Learn site as well? I've looked through the docs and didn't see anything.
No, there is currently no route to explicitly log out, or log in. You can, however, use the Valence auth process to generate credentials for a new user. What you need to do in that case is use a browser to interact with the user that doesn't have an open session with the LMS: as long as the LMS thinks that the browser doing the user part of the authentication has an open session, it will pass back the user credentials for that user instead of asking the user to re-authenticate.
Typically an inactive session with the LMS expires after a short time and then the LMS will force the user to re-authenticate if your app initiates the auth process.

how to check if shopify session has expired?

say I have this call in my code:
products = shopify.Product.find()
which works if I am just logged in, but after some time it starts failing with an error saying AttributeError: 'NoneType' object has no attribute 'find'. I think this happens because the session expires and my code does not check that.
is there a way to check if shopify session has expired? I store the store URL and the authentication token in my webapp2 session thus:
self.session['shopify'] = {
'shop_url': shopify_session.url,
'access_token': shopify_session.token
}
are there any other properties that I need to store in my web session that I can use to check if the shopify session has expired?
Shopify access_token never expires, the one that expires or been reset is your session.
If you are using a shared hosting then the probability of resetting the session is much higher since they reset the application pool very frequent.
If this is the case then you should consider using persistent session rather than memory session. If you are using .NET then you can read ASP.NET State Management and Configure SQL Server for ASP.NET SQL Server Session State.
It depends on your access mode, if you want a permanent access token, you should use offline access mode, online access mode get expires after the user session expires.
https://shopify.dev/concepts/about-apis/authentication#api-access-modes