Documentation
¶
Index ¶
- func CheckSessionExpired(session Session, ctx context.Context, ...) bool
- func NeedsReauthentication(fp *SessionFingerprint, timeout time.Duration) bool
- func UpdateAuthTime(fp *SessionFingerprint)
- func UpdateSessionFingerprint(fp *SessionFingerprint, r *http.Request)
- func VerifySessionFingerprint(fp *SessionFingerprint, r *http.Request) bool
- type Manager
- func (m *Manager) Create() (Session, error)
- func (m *Manager) DisableAutoGC() error
- func (m *Manager) EnableAutoGC(interval time.Duration) error
- func (m *Manager) GetSession(ctx *mist.Context) (Session, error)
- func (m *Manager) InitSession(ctx *mist.Context) (Session, error)
- func (m *Manager) InitSessionWithSecurity(ctx *mist.Context, options *SessionSecurityOptions) (Session, error)
- func (m *Manager) RefreshSessionWithSecurity(ctx *mist.Context, options *SessionSecurityOptions) error
- func (m *Manager) RemoveSession(ctx *mist.Context) error
- func (m *Manager) RequireReauthForSensitiveOperation(ctx *mist.Context, options *SessionSecurityOptions) (bool, error)
- func (m *Manager) RunGC() error
- func (m *Manager) SetMaxAge(maxAge int)
- func (m *Manager) SetSecurityOptions(options *SessionSecurityOptions)
- type Propagator
- type Session
- type SessionFingerprint
- type SessionSecurityOptions
- type Store
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CheckSessionExpired ¶ added in v0.1.26
func CheckSessionExpired(session Session, ctx context.Context, absoluteTimeout, idleTimeout time.Duration) bool
CheckSessionExpired 检查会话是否过期
func NeedsReauthentication ¶ added in v0.1.26
func NeedsReauthentication(fp *SessionFingerprint, timeout time.Duration) bool
NeedsReauthentication 检查是否需要重新认证
func UpdateAuthTime ¶ added in v0.1.26
func UpdateAuthTime(fp *SessionFingerprint)
UpdateAuthTime 更新最后认证时间
func UpdateSessionFingerprint ¶ added in v0.1.26
func UpdateSessionFingerprint(fp *SessionFingerprint, r *http.Request)
UpdateSessionFingerprint 更新会话指纹
func VerifySessionFingerprint ¶ added in v0.1.26
func VerifySessionFingerprint(fp *SessionFingerprint, r *http.Request) bool
VerifySessionFingerprint 验证会话指纹
Types ¶
type Manager ¶
type Manager struct {
Store // Handles storage and retrieval of session data.
Propagator // Manages transmission of session identifiers in HTTP messages.
CtxSessionKey string // Key for session object storage in request context.
// contains filtered or unexported fields
}
The Manager struct acts as a centralized component that orchestrates the session management within a web application. By embedding the Store and Propagator interfaces, it seamlessly combines the functionality of session storage and identifier propagation. The Manager handles the complete lifecycle of a session, which includes creating sessions, storing them, transmitting session identifiers in HTTP messages, and cleaning up as needed. This higher-level struct allows for simplified session management throughout the application, as it encapsulates all the necessary operations within a single entity.
Fields:
- CtxSessionKey: A string that represents the key under which the session object is stored in the context of an HTTP request. This allows middleware and handlers to retrieve the session info from the context using this key, facilitating a standard way of accessing session data during the processing of a request.
- autoGC: A bool indicating whether automatic garbage collection is enabled to periodically clean up expired sessions.
- gcInterval: The duration between garbage collection runs.
- gcCtx: Context for the garbage collection goroutine, used to cancel it when needed.
- gcCancel: Function to cancel the garbage collection context.
- mutex: Mutex to protect concurrent access to the Manager's state.
The inclusion of both the Store and Propagator interfaces suggests that any instance of Manager is capable of performing all session-related operations defined by these interfaces. This includes generating and managing session data (through the Store interface) and handling the session identifiers across HTTP requests and responses (through the Propagator interface).
Here is an example of how the Manager struct could be initialized and used within an application:
func main() {
// Initialize the session manager with specific implementations of Store and Propagator.
sessionManager := &Manager{
Store: NewRedisStore(), // assuming NewRedisStore returns an implementation of Store
Propagator: NewCookiePropagator("session_id"), // assuming NewCookiePropagator returns an implementation of Propagator
CtxSessionKey: "session", // the key used to store session objects in context
}
// Enable automatic garbage collection every 10 minutes
sessionManager.EnableAutoGC(10 * time.Minute)
// Set up your HTTP server, routes, middleware, etc.,
// and use sessionManager to manage sessions in your application.
}
Through Manager, all handlers and middleware in the application can interact with sessions using a standardized interface without worrying about the underlying storage or communication mechanisms, which are abstracted away by the implementations of Store and Propagator.
Implementers of the Manager struct should ensure that necessary synchronizations or concurrent access handling are considered in their implementations of Store and Propagator to prevent race conditions or data inconsistencies.
func NewManager ¶ added in v0.1.19
NewManager creates and initializes a new session Manager with the specified session store and maximum age for sessions. This function is the primary way to create a Manager instance, ensuring that it is properly configured with the necessary components for session management.
Parameters:
- store: An implementation of the Store interface that will be used to persist session data. This could be an in-memory store for simple applications, a Redis store for distributed applications, or any other implementation that satisfies the Store interface.
- maxAge: An integer representing the maximum age of a session in seconds. This value will be used to configure the cookie option in the Propagator to control how long session identifiers remain valid on the client side.
Returns:
- *Manager: A pointer to the newly created and initialized Manager instance, ready to be used for session management within your application.
- error: An error if something goes wrong during the creation process.
The Manager's CtxSessionKey is set to "session" by default, which is the key used to store session data in the mist.Context's UserValues map. This can be changed after creation if a different key is desired.
This function also initializes the Propagator component of the Manager with an implementation from the cookie package, which handles the transfer of session identifiers between the server and the client via cookies.
Example usage:
// Create a new Redis-based session store
redisStore, err := redis.NewStore(&redis.Options{Addr: "localhost:6379"})
if err != nil {
// Handle error
}
// Create a new Manager with the Redis store and a 30-minute maximum age
manager, err := NewManager(redisStore, 1800)
if err != nil {
// Handle error
}
// Use the manager to handle sessions in your HTTP handlers
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
ctx := mist.NewContext(r, w)
sess, err := manager.GetSession(ctx)
// ...
})
func (*Manager) Create ¶ added in v0.1.19
Create generates a new session with a randomly generated ID. This is a convenience method that can be used when you need to create a session without a specific ID or when you want to create a session outside of the normal HTTP request/response cycle.
Returns:
- Session: The newly created session.
- error: An error if the session could not be created.
This method uses the embedded Store's Generate method to create a new session with a randomly generated UUID. It uses the background context since there is no request context available.
Example:
// Create a new session
sess, err := manager.Create()
if err != nil {
// Handle error
}
// Use the session
err = sess.Set(context.Background(), "user_id", 123)
func (*Manager) DisableAutoGC ¶ added in v0.1.20
DisableAutoGC stops the automatic garbage collection of expired sessions. This method stops the background goroutine that was started by EnableAutoGC. After calling this method, sessions will no longer be automatically cleaned up, and the application will need to manually call the GC method of the Store to remove expired sessions.
Returns:
- error: An error if automatic GC could not be disabled.
This method is safe to call from multiple goroutines as it uses a mutex to protect the Manager's state. If automatic GC is not enabled, this method does nothing and returns nil.
Example:
// Disable automatic GC
err := manager.DisableAutoGC()
if err != nil {
// Handle error
}
func (*Manager) EnableAutoGC ¶ added in v0.1.20
EnableAutoGC activates the automatic garbage collection of expired sessions. This method starts a background goroutine that periodically calls the GC method of the session Store to clean up expired sessions. This is important for managing server resources by preventing memory leaks from abandoned sessions.
Parameters:
- interval: The time.Duration between garbage collection runs. This should be set to a reasonable value based on the expected number of sessions and the server's resource constraints. Too frequent GC can impact performance, while too infrequent GC can lead to resource exhaustion.
Returns:
- error: An error if the automatic GC could not be enabled.
The garbage collection goroutine will continue running until DisableAutoGC is called or the Manager instance is garbage collected. The goroutine uses a context for cancellation, which is stored in the Manager's gcCtx field and can be canceled using the gcCancel function.
This method is safe to call from multiple goroutines as it uses a mutex to protect the Manager's state. If automatic GC is already enabled, this method will stop the existing GC goroutine and start a new one with the provided interval.
Example:
// Enable automatic GC every 10 minutes
err := manager.EnableAutoGC(10 * time.Minute)
if err != nil {
// Handle error
}
func (*Manager) GetSession ¶
GetSession is a method that retrieves the current user's session from the HTTP request and caches it in the context for future use within the scope of the current request processing. This method provides a single entry point for session retrieval, and ensures that the session is loaded only once per request, thereby improving performance and reducing redundant operations.
The flow is as follows:
- It first checks if the UserValues map within the mist.Context is initialized. If not, it initializes the map to store the session object later in the process.
- The method then tries to retrieve the session from the UserValues map using the CtxSessionKey defined in the Manager struct. This is to check if the session was already fetched and cached earlier in the current request lifecycle.
- If the session is found in the map, it is returned immediately, avoiding any further operations.
- If not, the method utilizes the Propagator interface's Extract method to retrieve the session identifier from the incoming HTTP request, which is typically read from a cookie or request header.
- With the session identifier obtained, the method then fetches the actual session data using the Store interface's Get method. This method call also passes along the context from the request to handle any session-related context operations such as deadlines or cancellations.
- After the session is successfully retrieved, it is stored in the UserValues map using the CtxSessionKey for quick access during subsequent calls within the same request lifecycle.
- Finally, the actual session data or an error (if any occurred while retrieving the session identifier or the session data) is returned.
If at any point there is a failure to retrieve the session identifier or the session data, an error is returned to the caller. This method centralizes error handling related to session retrieval, which simplifies the session logic elsewhere in the application.
The mist.Context is assumed to be a custom HTTP context that contains both the standard library context and additional data fields used for managing user-specific values within a single request lifecycle.
Usage: This method should be called by middlewares or handlers that require access to the current user's session. It exempts them from having to handle low-level session extraction and storage mechanisms directly.
func (*Manager) InitSession ¶
InitSession is responsible for creating a new session and associating it with the client who initiated the HTTP request. It is typically called when a new user visits the application and a new session needs to be established. The method leverages the capabilities of the embedded interfaces within the Manager struct to generate a unique session identifier, create a new session, and transmit this session identifier back to the client for future interactions.
The process involves the following steps:
- Generate a new unique identifier for the session using a universally unique identifier (UUID) library.
- With the new session identifier, the method calls the Generate method of the embedded Store interface to actually create a new session in the session store. This session creation is supposed to associate the generated UUID with a new session object and store it in whatever storage mechanism the Store interface implementation uses (e.g., in-memory, database, etc.). The request context is provided to handle any necessary context operations such as deadlines or request cancellations.
- If an error occurs during session generation (e.g., database error, context deadline exceeded), this error is returned to the caller and no further steps are taken.
- Should the session generation be successful, the new identifier is then propagated to the client using the Inject method of the Propagator interface which is part of the Manager. This step typically involves setting a cookie or an HTTP header in the response so that the client can include this identifier in subsequent requests to maintain the session context.
- The new session object is returned to the caller along with any error that might occur during the identifier injection process (though no error is expected in creating a new session at this point, errors might occur while setting an HTTP response header or cookie).
It's important for the implementer to note that after this method is called, the client must include the session identifier in subsequent requests, and the server will need to handle this identifier to retrieve the associated session from the store.
The mist.Context parameter provides request-specific information including the Request and ResponseWriter which are used to retrieve and set information related to the session. This context is assumed to be part of a custom processing pipeline that allows easy access and manipulation of HTTP request and response data.
Usage: This method should be called when a new user session needs to be initiated. Typically, it would be invoked within the auth process, or when a session is not found for a request and needs to be created.
Example:
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
ctx := mist.NewContext(r, w)
session, err := sessionManager.InitSession(ctx)
if err != nil {
// Handle error
}
// Session initialized successfully, store session data or modify response as needed.
})
func (*Manager) InitSessionWithSecurity ¶ added in v0.1.26
func (m *Manager) InitSessionWithSecurity(ctx *mist.Context, options *SessionSecurityOptions) (Session, error)
InitSessionWithSecurity 使用安全选项初始化会话
func (*Manager) RefreshSessionWithSecurity ¶ added in v0.1.26
func (m *Manager) RefreshSessionWithSecurity(ctx *mist.Context, options *SessionSecurityOptions) error
RefreshSessionWithSecurity 使用安全选项刷新会话
func (*Manager) RemoveSession ¶
RemoveSession is a method designed to delete a user's session from the session store and to clear any session identifiers from the client's context, effectively logging the user out. This can be a critical function for user security, ensuring sessions are properly terminated when a user logs out or when their session should be invalidated for other reasons, such as after changing a password, after a period of inactivity, or for administrative logout purposes.
The flow of the session removal process operates as follows:
- Attempt to retrieve the existing session from the mist.Context by calling the GetSession method of the Manager struct, which retrieves session data based on a session identifier found in the client's request.
- If an error is encountered during session retrieval, such as when the session does not exist or the session identifier is invalid, the error is immediately returned and the refresh operation is aborted.
- Once the session is successfully retrieved, the Manager struct's embedded Store interface is used to remove the session data from the persistent session storage via the Store.Remove method. This requires the context from the current HTTP request (for deadline or cancellation purposes) and the session ID.
- Any error during the session removal from the store is returned immediately, indicating a failure to fully remove the session.
- If the session data is successfully removed from the store, the manager proceeds to request that the session identifier be removed from the client's session context by calling the Remove method of the Propagator interface. This typically involves instructing the client (often via an HTTP cookie) to discard the session identifier, thus preventing it from being included in future requests.
- The final error from the Propagator Remove operation is returned, which may indicate if there was a problem with instructing the client to discard the session (e.g., if the HTTP headers have already been sent).
This method completes the lifecycle management of a session, providing a clean and secure way to end a user's session when it is no longer needed or valid. Proper session termination is an important aspect of web application security, as it helps prevent unauthorized access via stale session IDs.
The mist.Context refers to a custom context object which typically combines the standard Go Context with HTTP request and response handling, allowing easier manipulation of HTTP session management.
func (*Manager) RequireReauthForSensitiveOperation ¶ added in v0.1.26
func (m *Manager) RequireReauthForSensitiveOperation(ctx *mist.Context, options *SessionSecurityOptions) (bool, error)
RequireReauthForSensitiveOperation 检查并要求重新认证敏感操作
func (*Manager) RunGC ¶ added in v0.1.20
RunGC manually runs garbage collection on the session store. This method is useful when automatic garbage collection is disabled or when you want to immediately clean up expired sessions without waiting for the next automatic GC cycle.
Returns:
- error: An error if the garbage collection failed.
This method uses a background context with a 30-second timeout to ensure that the garbage collection operation doesn't run indefinitely. If the GC operation takes longer than 30 seconds, it will be canceled.
Example:
// Manually run garbage collection
err := manager.RunGC()
if err != nil {
// Handle error
}
func (*Manager) SetMaxAge ¶ added in v0.1.19
SetMaxAge adjusts the maximum age of session cookies. This method updates the CookieOption function within the underlying cookie propagator to set a new MaxAge value. The MaxAge value is specified in seconds and determines how long the session cookie will remain valid in the client's browser.
Parameters:
- maxAge: The new maximum age of the session cookie in seconds. A positive value indicates how many seconds the cookie will remain valid for. A negative value means the cookie will be deleted when the browser session ends. A zero value indicates that the cookie should be deleted immediately.
This method is typically used to adjust session lifetimes based on application requirements or to implement features like "remember me" by extending the session duration when requested.
Note that this method only affects the cookies set after this method is called. Existing cookies that have already been sent to clients will not be affected until they interact with the server again and receive a new cookie.
Example:
// Set session cookies to expire after 7 days (604800 seconds) manager.SetMaxAge(604800) // Set session cookies to expire when the browser is closed manager.SetMaxAge(-1) // Set session cookies to be deleted immediately manager.SetMaxAge(0)
func (*Manager) SetSecurityOptions ¶ added in v0.1.26
func (m *Manager) SetSecurityOptions(options *SessionSecurityOptions)
SetSecurityOptions 设置会话安全选项
type Propagator ¶
type Propagator interface {
Inject(id string, writer http.ResponseWriter) error // Add a session identifier to the HTTP response
Extract(req *http.Request) (string, error) // Retrieve a session identifier from the HTTP request
Remove(writer http.ResponseWriter) error // Delete a session identifier from the HTTP response
}
The Propagator interface defines methods responsible for managing the propagation of session identifiers across HTTP requests and responses in a web application. This interface abstracts the operations of adding, retrieving, and deleting a session identifier (such as a cookie or a auth) to and from HTTP requests and responses, thereby allowing session tracking and management universally across different systems and components. Methods:
- Inject(id string, writer http.ResponseWriter) error: Inserts a session identifier 'id' into an outgoing HTTP response using the provided ResponseWriter. This is typically used to set a cookie or an HTTP header that contains the session identifier, enabling the client (e.g., a web browser) to return the identifier in subsequent requests to maintain the session state. If there's an issue writing to the response (e.g., headers already written), the method should return an error.
- Extract(req *http.Request) (string, error): Analyzes an incoming HTTP request and extracts the session identifier. This is commonly used to read a cookie or a header from the request, validating its presence and perhaps its format or integrity. If the session identifier is successfully retrieved, it is returned; otherwise, an error is returned, which may indicate that the session identifier is not present or invalid.
- Remove(writer http.ResponseWriter) error: Clears the session identifier from the outgoing HTTP response, effectively terminating the session from the server's perspective. This is generally implemented by invalidating a cookie or clearing a header in the response. If there's a problem modifying the response (e.g., if it's too late to change headers), the method should return an error.
Session identifiers are typically compact and should be handled in a secure manner to prevent security vulnerabilities such as Session Hijacking or Session Fixation. Implementers should ensure that identifiers are properly encrypted or signed and handled over secure channels when necessary. An example implementation might look like:
type CookiePropagator struct {
// CookieName defines the name of the cookie to be used for session identification.
CookieName string
// Other configuration for the cookie such as Domain, Path, Secure flags, etc.
}
func (cp *CookiePropagator) Inject(id string, writer http.ResponseWriter) error {
// ... set cookie with the session id ...
}
func (cp *CookiePropagator) Extract(req *http.Request) (string, error) {
// ... read and return the session id from the request cookie ...
}
func (cp *CookiePropagator) Remove(writer http.ResponseWriter) error {
// ... invalidate the cookie to remove the session ...
}
This interface is essential for ensuring session continuity and coherence in stateful web applications, providing a high-level abstraction over the raw HTTP mechanisms used underneath.
type Session ¶
type Session interface {
Get(ctx context.Context, key string) (any, error) // Retrieve a value from the session
Set(ctx context.Context, key string, value any) error // Store a value in the session
Delete(ctx context.Context, key string) error // Remove a value from the session
ID() string // Return the session's unique identifier
Save() error // Save any changes to the session
IsModified() bool // Check if the session has been modified
SetMaxAge(seconds int) // Set session's maximum lifetime
}
Session is an interface that defines the contract for a session management system. In web applications, a session represents a single user's interactions with the application across multiple requests. It is used to store and retrieve data specific to a user or session scope. The Session interface allows for getting and setting of session values and retrieval of a unique session identifier. Session implementations should handle concurrency and provide some form of persistence mechanism, which could range from in-memory storage to database-backed solutions. These operations are context-aware, allowing them to participate in context-specific lifecycles, such as request timeouts or cancellations. Methods:
- Get(ctx context.Context, key string) (any, error): Retrieves a value from the session data. The 'key' argument specifies which value to retrieve. If the key does not exist, the method should return nil without error. An error is returned only if there is a problem with the retrieval process itself, not if the key is merely absent.
- Set(ctx context.Context, key string, value any) error: Assigns a 'value' to a 'key' in the session data. If the 'key' already exists, the value should be overwritten. As with 'Get', any context-related behavior should be handled within this method. If there is an error while setting the value (e.g., write failure), an error should be reported back to the caller.
- Delete(ctx context.Context, key string) error: Removes a value associated with 'key' from the session. If the key does not exist, this operation should be a no-op and not return an error.
- ID() string: This method returns the unique identifier for the session. Typically, this identifier is generated when the session is first created and remains constant throughout the session's lifecycle. The ID is used to link a session to a specific user or interaction sequence.
- Save() error: Saves any changes to the session. This may be a no-op for some implementations if changes are immediately persisted.
- IsModified() bool: Returns whether the session has been modified since it was last saved. This is useful for optimizations to avoid unnecessary storage operations.
- SetMaxAge(seconds int): Sets the maximum lifetime of the session in seconds. This can be used to control session expiration time based on application logic.
Usage and Implementation Notes: The 'Session' type assumes 'any' type for stored values, allowing for flexibility in what kinds of data can be stored in the session. However, the underlying implementation needs to ensure proper serialization and deserialization of these values as sessions may be persisted across different requests and even server restarts. It is important to ensure thread safety within the methods if the session store is accessed concurrently. Sessions should also handle cleanup and invalidation as necessary, and the implementation should detail how long session values persist (e.g., expiry time, persistent or ephemeral storage). As an example, an implementation could use a synchronized map structure to store session values, with an additional expiration timestamp to handle session lifetimes:
type InMemorySession struct {
id string
values sync.Map // Thread-safe map to store session values
expiry time.Time // Expiration time of the session
modified bool // Flag to indicate if the session has been modified
// ... additional session properties and mutexes ...
}
func (s *InMemorySession) Get(ctx context.Context, key string) (any, error) {
// ... retrieve value from the session ...
}
func (s *InMemorySession) Set(ctx context.Context, key string, value any) error {
// ... set value in the session ...
s.modified = true
return nil
}
func (s *InMemorySession) Delete(ctx context.Context, key string) error {
// ... delete value from the session ...
s.modified = true
return nil
}
func (s *InMemorySession) ID() string {
return s.id
}
func (s *InMemorySession) Save() error {
// ... save session data ...
s.modified = false
return nil
}
func (s *InMemorySession) IsModified() bool {
return s.modified
}
func (s *InMemorySession) SetMaxAge(seconds int) {
// ... set session max age ...
}
The above example provides a simple template for how session data can be managed within a web application. It emphasizes the importance of thread-safe data access and context management.
type SessionFingerprint ¶ added in v0.1.26
type SessionFingerprint struct {
IP string
UserAgent string
CreatedAt time.Time
LastSeenAt time.Time
LastAuthAt time.Time
}
SessionFingerprint 存储会话指纹信息
func GenerateSessionFingerprint ¶ added in v0.1.26
func GenerateSessionFingerprint(r *http.Request) *SessionFingerprint
GenerateSessionFingerprint 生成会话指纹
type SessionSecurityOptions ¶ added in v0.1.26
type SessionSecurityOptions struct {
// EnableSameSite 启用SameSite cookie策略
EnableSameSite bool
// SameSiteMode 设置SameSite模式 (None, Lax, Strict)
SameSiteMode http.SameSite
// SecureOnly 仅在HTTPS下使用
SecureOnly bool
// HttpOnly 阻止JavaScript访问cookie
HttpOnly bool
// EnableFingerprinting 启用会话指纹绑定
EnableFingerprinting bool
// RotateTokenOnValidation 每次认证成功后轮换会话令牌
RotateTokenOnValidation bool
// AbsoluteTimeout 会话绝对过期时间(无论活动与否)
AbsoluteTimeout time.Duration
// IdleTimeout 会话闲置超时时间
IdleTimeout time.Duration
// RenewTimeout 会话续期时间阈值
RenewTimeout time.Duration
// RequireReauthForSensitive 敏感操作需要重新验证
RequireReauthForSensitive bool
// ReauthTimeout 重新验证超时时间
ReauthTimeout time.Duration
}
SessionSecurityOptions 定义会话安全选项
func DefaultSessionSecurityOptions ¶ added in v0.1.26
func DefaultSessionSecurityOptions() *SessionSecurityOptions
DefaultSessionSecurityOptions 返回默认的会话安全选项
type Store ¶
type Store interface {
Generate(ctx context.Context, id string) (Session, error) // Create a new session
Refresh(ctx context.Context, id string) error // Extend a session's life
Remove(ctx context.Context, id string) error // Delete an existing session
Get(ctx context.Context, id string) (Session, error) // Retrieve a session's data
GC(ctx context.Context) error // Garbage collect expired sessions
}
The Store interface defines a set of methods for session management in an application. This interface requires any session store implementation to create, refresh, remove, and retrieve sessions. A session typically represents a period of interaction between a user and an application and can hold crucial data such as user identity, preferences, and application state. The operations to manipulate these sessions are context-aware, meaning they can be cancelled, have timeouts attached to them, or carry request-scoped values via the provided context.Context object. This interface allows an application to abstract away the details of how sessions are stored and managed, whether it's in memory, a database, a file system, or some other form of storage. Methods:
- Generate(ctx context.Context, id string) (Session, error): Responsible for creating a new session with the given identifier 'id'. It returns the newly created Session object and any error encountered during the creation process. This is typically called during user login or initial interaction.
- Refresh(ctx context.Context, id string) error: Updates an existing session's expiration or last active time, if applicable, to prevent the session from expiring. This is typically used for extending user sessions to keep them logged in or maintaining their state.
- Remove(ctx context.Context, id string) error: Deletes a session from the store, effectively logging out the user or clearing any state stored in the session. This occurs when a user explicitly logs out or when a session needs to be invalidated for security reasons.
- Get(ctx context.Context, id string) (Session, error): Retrieves the session associated with the given identifier 'id'. It returns the Session object if it exists and any error that occurs during the retrieval. This is called whenever an application needs to access the session data for a request.
- GC(ctx context.Context) error: Performs garbage collection on expired sessions to free up resources. This should be called periodically to clean up stale session data.
The 'Session' type mentioned in the methods is expected to be an interface or a struct that encapsulates the session data. The specific implementation of 'Session' will depend on the application's requirements. Note that this interface does not specify how to handle session collision or the specifics of session expiration details. Implementations of this interface should ensure these aspects are handled according to their needs and document any specific behaviors. Example Implementation: An in-memory store could implement the Store interface like so:
type InMemoryStore struct {
sessions map[string]Session
lock sync.RWMutex
// ... additional fields and methods ...
}
func (s *InMemoryStore) Generate(ctx context.Context, id string) (Session, error) {
// ... generate and store a new session ...
}
func (s *InMemoryStore) Refresh(ctx context.Context, id string) error {
// ... refresh session expiration time ...
}
func (s *InMemoryStore) Remove(ctx context.Context, id string) error {
// ... remove session from store ...
}
func (s *InMemoryStore) Get(ctx context.Context, id string) (Session, error) {
// ... retrieve a session based on the id ...
}
func (s *InMemoryStore) GC(ctx context.Context) error {
// ... garbage collect expired sessions ...
}
The above interface abstraction enables one to switch session store implementations with minimal changes to the overall application logic, providing flexibility and scalability for session management strategies.