How do I know that session cookie has expired?

973 views
Skip to first unread message

Taher Alkhateeb

unread,
Feb 28, 2021, 8:22:12 AM2/28/21
to mo...@googlegroups.com
Hey folks,

So if we assume I make the following:

1. Create a login request e.g. /rest/s1/pop/login
2. Save the JSESSIONID on the client side
3. Make more requests using that cookie

My understanding is that then this cookie will increase its lifespan as
long as you keep using it.

However, my problem is in understanding how to _know_ that it has
expired? Candidate answers are:

1. That it returns status code 403
2. Parse the error string "User [No User] is not authorized"

Problem with 1 is that you cannot differentiate between unauthorized
access or cookie expired. Problem with 2 is that it feels like an ugly
hack that I have to depend on error string.

So any suggestions are appreciated.

--

Taher Alkhateeb

David E Jones

unread,
Feb 28, 2021, 6:49:57 PM2/28/21
to Moqui Framework
The session token will change if the session has expired and a new session is created for a given HTTP request.

When using a session with POST requests Moqui enforces a session token in the X-CSRF-Token header (or the old moquiSessionToken header, still supported but not recommended). This means in your client you need to look for the X-CSRF-Token header in the HTTP response and remember it locally to use for future requests.

By security design you don't have access to the session cookie from JavaScript (and, BTW, the cookie name is not guaranteed to be JSESSIONID), but you do have access to the X-CSRF-Token header and must in order to use it as intended. If you get a HTTP response with a value in the X-CSRF-Token header that is different from the one you have remembered then you know the session has changed (and unless there was an explicit logout or login the session will mostly only change on a timeout, though could be other things like a server going down).

-David


--
You received this message because you are subscribed to the Google Groups "Moqui Ecosystem" group.
To unsubscribe from this group and stop receiving emails from it, send an email to moqui+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moqui/2e1f88dd-98fe-3cb6-eae8-f05d03814d04%40pythys.com.

Taher Alkhateeb

unread,
Mar 1, 2021, 8:17:08 AM3/1/21
to mo...@googlegroups.com

Hi David,

I'm a little confused because I'm not sure in your explanation which cookie are you referring to. So can you confirm this:

- We need BOTH the JSESSIONID and x-csrf-token to make POST requests
- If request x-csrf-token != response x-csrf-token then the login session has expired
- We pass the JSESSIONID as a cookie {Cookie: JSESSIONID=node01x0r91biet8065lsw04sxm3kh88.node0}
- We pass the x-csrf-token as a header {x-csrf-token: W9n6eVjtFYH-9x6oLh1n, MxriYKIEdb9SReZx7eFi}

Is my understanding correct in here? The reason I ask is because I cannot access the system with JSESSIONID right now.

--

Taher Alkhateeb

Taher Alkhateeb

unread,
Mar 1, 2021, 8:17:18 AM3/1/21
to mo...@googlegroups.com

Hi David,

I'm a little confused because I'm not sure in your explanation which cookie are you referring to. So can you confirm this:

- We need BOTH the JSESSIONID and x-csrf-token to make POST requests
- If request x-csrf-token != response x-csrf-token then the login session has expired
- We pass the JSESSIONID as a cookie {Cookie: JSESSIONID=node01x0r91biet8065lsw04sxm3kh88.node0}
- We pass the x-csrf-token as a header {x-csrf-token: W9n6eVjtFYH-9x6oLh1n, MxriYKIEdb9SReZx7eFi}

Is my understanding correct in here? The reason I ask is because I cannot access the system without JSESSIONID right now.

--

Taher Alkhateeb

On 3/1/21 2:49 AM, David E Jones wrote:

Taher Alkhateeb

unread,
Mar 3, 2021, 3:38:09 PM3/3/21
to mo...@googlegroups.com

Hello,

OK Partially answering myself and I think this is the minimum needed:

- GET request: I must pass the JSESSIONID cookie
- POST request: I must pass the JSESSIONID cookie + X-CSRF-Token
- Check expiry: If saved X-CSRF-Token has changed

Example GET:

curl -X GET --header 'Cookie: JSESSIONID=node0n83qfflrv5gy1q26l2amicuke248.node0' 'https://host-here/rest/s1/mantle/products/DEMO_1_1'

Example POST:

curl -X POST  --header 'X-CSRF-Token: 9X9gCwRhjh26d397I5RK'  --header 'Cookie: JSESSIONID=node0n83qfflrv5gy1q26l2amicuke248.node0'  --header 'Content-Type: application/json'  --header 'Accept: application/json'  -d '{"_entity":"enums","enumId":"123"}'  'https://host-here/rest/s1/moqui/basic/enums'

Thank you again for all the help.

--

Taher Alkhateeb

Zhang Wei

unread,
Mar 3, 2021, 8:14:34 PM3/3/21
to mo...@googlegroups.com
I don't think you need to pass JSESSIONID manually if you are in one client instance. Just make sure the cookie is supported by the client. Like you are in a browser.



--
Zhang Wei

Taher Alkhateeb

unread,
Mar 4, 2021, 3:15:55 AM3/4/21
to mo...@googlegroups.com

Yeah well the problem is that the only platform where cookies are handled automatically are in the browser. if you have a mobile app then it's a different story and you _must_ pass the JSESSIONID. I tested this a lot and I don't think we have any other way. So even if let's say we are not guaranteed that the cookie will continue to have the name JSESSIONID, there is no alternative but to fetch that thing and handle it.

In other words, the browser is the "easy" problem. It's the other platforms that force me to think of and test everything.

Taher Alkhateeb

unread,
Mar 4, 2021, 3:34:25 AM3/4/21
to mo...@googlegroups.com

OH I just remembered one more thing that might shed some light on why I was confused for a while. It was a communication problem from my end. I summarize it as follows:

- If you are on a browser, you don't need to worry about anything except the X-CSRF-Token. You need it to make POST requests and you need it to know if your session has expired
- Also on the browser, you _cannot_ access cookies from Javascript, it's just a security thing in browsers
- However, if you use an http client that is NOT a browser, then you _do_ have access to the Set-Cookie header and you can extract what you want.

Bottom line:

- Don't think of anything except X-CSRF-Token on the browser
- Otherwise you MUST get your hands on the JSESSION cookie and handle it the way I showed in the curl example commands in this thread

It was my mistake for not communicating clearly that I'm _not_ working with a browser which lead to this miscommunication. I'm writing this for permanent record for anyone facing similar issues.

David E Jones

unread,
Mar 4, 2021, 3:47:25 AM3/4/21
to Moqui Framework
If your mobile app is a sufficiently trusted environment to save username and password for convenience then you can just pass username and password with every request, or get a long-term (one month or whatever) api key/token from the server to store locally in the client and pass with each request until it expires.

If your client environment is more trusted then you don't have to play the same games as in a browser. It's a totally different question.

One downside to not using sessions is you get a huge pile of mostly useless Visit records (one per session, new session per request means one per request), so if you plan on having lots of traffic I'd recommend disabling Visit tracking for the path they are on.

Taher Alkhateeb

unread,
Mar 4, 2021, 4:45:47 AM3/4/21
to mo...@googlegroups.com

Ah that's very informative thank you David.

In addition to what you mentioned about the visits, another problem with api_key is that session life is not extended automatically upon recent access which might not be a pleasant user experience "I use this app every day, why did it log me out?". So I have to re-write the already solved problem from moqui's side (extension of session life). 

Also, although the mobile app is a more trusted environment than the browser, it's still not THAT safe e.g. [1]. So unless JSESSIONID is a bad idea for other reasons? maybe that would be the best option for us?

[1] https://stackoverflow.com/questions/9233035/best-option-to-store-username-and-password-in-android-app

Cheers,

Taher Alkhateeb

Reply all
Reply to author
Forward
0 new messages