lzztt / koa-session-minimal

Minimal implementation of session middleware for Koa 2
MIT License
75 stars 13 forks source link

cant delete session #6

Closed yuu2lee4 closed 7 years ago

yuu2lee4 commented 7 years ago

image

although i set session to null in a setTimeout, and terminal also show it is null, but when i call getPin int the second, the ctx.session.pin has a value

image

my enviroment: macos, node 7.2.0, koa-session-minimal-3.0.2, koa-generic-session-mongo-0.3.0

yuu2lee4 commented 7 years ago

image and i found a strange thing, i seted session.user, then i console it, the object has no 'sid' and 'ttl' , but after i setted session.pin , it has 'sid' and 'ttl'

lzztt commented 7 years ago

and i found a strange thing, i seted session.user, then i console it, the object has no 'sid' and 'ttl' , but after i setted session.pin , it has 'sid' and 'ttl'

Hi yuu2lee4,

For the second question, looks like mongo store modified the session data before saving it (in set(sid, sess, ttl)).

created a task for koa-generic-session-mongo

lzztt commented 7 years ago

For the first question "cannot delete session", can you move the code out of the setTimeout() function?

Koa uses co-routine for async programming. Middlewares synchronize (pause/resume) their execution based on async/await calls (Promises). setTimeout() is an async call based on time, lives outside of the co-routine synchronization. So it cannot cooperate with any Koa middlewares, i.e., the session middleware could finish saving the session data to the underneath store before the setTimeout call get executed (set session = null). Middlewares don't yield the setTimeout call.

Let me know if you need more help.

yuu2lee4 commented 7 years ago

as you see, i want remove session.pin after 2 minutes when getPin was called by browser.i will write a async function called removePin based on setTimeout, and use it like this: replacing setTimeout with removePin in getPin, but not use await in case of blocking setTing ctx.body, if it dont help, the plan B is: after 2 minutes, the browser call the interfac removePin, then the koa remove the session.pin i will let you know if it worked

lzztt commented 7 years ago

Hi yuu2lee4,

It would be more reliable to do it on the server side (not depending on the browser and network). I can think of 3 ways to do this:

  1. manipulate session data directly in the database (session store). Do a query on the session collection in MongoDB, find documents that contain "pin" and remove "pin" if the session is older than 2 minutes, keep the rest of the session data.
  2. set a TTL for pin. In session, you would have "pin" and "pin_ttl" data. Your application can ignore the "pin" if the "pin_ttl" is expired (older than 2 minutes)
  3. set the TTL for sessions that contain "pin" to 2 minutes.

For the 1st solution, it can be handled by a separated script in any language, with a cron job that runs for every 2 minutes. For the 2nd solution, you need to save "pin_ttl" along with "pin". I use this method for the PIN generation for my website. For the 3rd solution, you can take advantage of the "dynamic expiration" feature of koa-session-minimal, to set the guest session to be expired after 2 minutes. Here is some code example for the 3rd solution (notice that the cookie option is dynamically returned by a function, the maxAge is calculated based on the existence of ctx.session.pin):

session({
  cookie: ctx => ({
    maxAge: ctx.session.pin ? TWO_MINUTES : ONE_MONTH,
    store: new MongoStore(),
  })
})

Let me know if this works for you.

yuu2lee4 commented 7 years ago

thanks for your help, the 3rd method works well.