alexedwards / scs

HTTP Session Management for Go
MIT License
2.09k stars 166 forks source link

Feature Request: enumerate all sessions #92

Closed Delphier closed 2 years ago

Delphier commented 4 years ago

In our application, want to implement a feature that is to view all online users and terminate a user session. I tried to get all the sessions to complete this feature, but did not find any method.

If using dbStore, I can get it directly from the database, but we use a memstore. I tried to read * MemStore directly, but his items field is private.

Hope to add a interface that can enumerate all sessions, which is very useful.

alexedwards commented 4 years ago

I can see that this would be useful, but would require changing the Store interface, which would be a breaking change for anyone using their own custom Store.

In the past, my response for this kind of request has always been to access the database directly like you suggest. But you're quite right... that doesn't work for MemStore.

We could potentially add a MemStore.Tokens() method which returns a slice of all non-expired tokens? You could then iterate through that, calling the MemStore.Find() method to fetch the user details and MemStore.Delete() method to remove a specific session.

Would that work?

Delphier commented 4 years ago

Thanks for your response, I think it works, and the changes are minimal.

alexedwards commented 3 years ago

I've just added an Iterate() method to SCS in commit https://github.com/alexedwards/scs/commit/eb62bb0aaffff869692cdb516da5bee65d62e3a2. Essentially, you pass the Iterate() method a closure with the signature func(ctx context.Context) error which contains the logic that you want to execute against each session.

For example, if you want to revoke all sessions with contain a userID value equal to 4 you can do the following:

err := sessionManager.Iterate(func(ctx context.Context) error {
    userID := sessionManager.GetInt(ctx, "userID")

    if userID == 4 {
        return sessionManager.Destroy(ctx)
    }

    return nil
})

if err != nil {
    log.Fatal(err)
}

Session iteration is currently supported by memstore and postgresstore store implementations via an new IterableStore interface. The Iterate() method checks that the store supports iteration before doing anything (it panics if it is not supported). I felt that this approach was better than making a breaking change to the Store interface.

alexedwards commented 2 years ago

Thanks to @gandaldf the IterableStore interface is now also supported by:

This leaves only the following stores which need to be updated still:

gandaldf commented 2 years ago

I'm planning to complete the list asap! I will PR a mssql store too, so scs will support more or less the same RDBMS that most ORMs support.

alexedwards commented 2 years ago

@gandaldf That sounds great, thank you :pray:

gandaldf commented 2 years ago

Here we go: #121

alexedwards commented 2 years ago

@gandaldf Thanks so much for your time and effort on this :+1:

I've merged your PR just now.