# Session

Middleware session provides session management for Macaron [Instances](https://go-macaron.com/core_concepts#instances).

* [GitHub](https://github.com/go-macaron/session)
* [API Reference](https://gowalker.org/github.com/go-macaron/session)

## Installation

```bash
go get github.com/go-macaron/session
```

## Usage

```go
import (
    "github.com/go-macaron/session"
    "gopkg.in/macaron.v1"
)

func main() {
    m := macaron.Classic()
    m.Use(macaron.Renderer())
    m.Use(session.Sessioner())

    m.Get("/", func(sess session.Store) string {
        sess.Set("session", "session middleware")
        return sess.Get("session").(string)
    })

    m.Get("/signup", func(ctx *macaron.Context, f *session.Flash) {
        f.Success("yes!!!")
        f.Error("opps...")
        f.Info("aha?!")
        f.Warning("Just be careful.")
        ctx.HTML(200, "signup")
    })

    m.Run()
}
```

```markup
<!-- templates/signup.tmpl -->
<h2>{{.Flash.SuccessMsg}}</h2>
<h2>{{.Flash.ErrorMsg}}</h2>
<h2>{{.Flash.InfoMsg}}</h2>
<h2>{{.Flash.WarningMsg}}</h2>
```

### Pongo2

If you're using [pongo2](https://github.com/go-macaron/pongo2) as template engine, you will use flash in HTML as follows:

```markup
<!-- templates/signup.tmpl -->
<h2>{{Flash.SuccessMsg}}</h2>
<h2>{{Flash.ErrorMsg}}</h2>
<h2>{{Flash.InfoMsg}}</h2>
<h2>{{Flash.WarningMsg}}</h2>
```

### Output flash in current response

By default, flash will be only used for the next coming response corresponding to the session, but functions `Success`, `Error`, `Info` and `Warning` are all accept a second argument to indicate whether output flash in current response or not.

```go
// ...
f.Success("yes!!!", true)
f.Error("opps...", true)
f.Info("aha?!", true)
f.Warning("Just be careful.", true)
// ...
```

But remember, flash can only be used once no matter which way you use.

## Options

`session.Sessioner` comes with a variety of configuration options([`session.Options`](https://gowalker.org/github.com/go-macaron/session#Options)):

```go
//...
m.Use(session.Sessioner(session.Options{
    // Name of provider. Default is "memory".
    Provider:       "memory",
    // Provider configuration, it's corresponding to provider.
    ProviderConfig: "",
    // Cookie name to save session ID. Default is "MacaronSession".
    CookieName:     "MacaronSession",
    // Cookie path to store. Default is "/".
    CookiePath:     "/",
    // GC interval time in seconds. Default is 3600.
    Gclifetime:     3600,
    // Max life time in seconds. Default is whatever GC interval time is.
    Maxlifetime:    3600,
    // Use HTTPS only. Default is false.
    Secure:         false,
    // Cookie life time. Default is 0.
    CookieLifeTime: 0,
    // Cookie domain name. Default is empty.
    Domain:         "",
    // Session ID length. Default is 16.
    IDLength:       16,
    // Configuration section name. Default is "session".
    Section:        "session",
}))
//...
```

## Providers

There are 9 built-in implementations of session provider, you have to import provider driver explicitly except for **memory** and **file** providers.

Following are some basic usage examples for providers.

### Memory

```go
//...
m.Use(session.Sessioner())
//...
```

### File

```go
//...
m.Use(session.Sessioner(session.Options{
    Provider:       "file",
    ProviderConfig: "data/sessions",
}))
//...
```

### Redis

```go
import _ "github.com/go-macaron/session/redis"

//...
m.Use(session.Sessioner(session.Options{
    Provider:       "redis",
    // e.g.: network=tcp,addr=127.0.0.1:6379,password=macaron,db=0,pool_size=100,idle_timeout=180,prefix=session:
    ProviderConfig: "addr=127.0.0.1:6379,password=macaron",
}))
//...
```

### Memcache

```go
import _ "github.com/go-macaron/session/memcache"

//...
m.Use(session.Sessioner(session.Options{
    Provider:       "memcache",
    // e.g.: 127.0.0.1:9090;127.0.0.1:9091
    ProviderConfig: "127.0.0.1:9090",
}))
//...
```

### PostgreSQL

Use following SQL to create database(make sure `key` length matches your `Options.IDLength`):

```sql
CREATE TABLE session (
    key       CHAR(16) NOT NULL,
    data      BYTEA,
    expiry    INTEGER NOT NULL,
    PRIMARY KEY (key)
);
```

```go
import _ "github.com/go-macaron/session/postgres"

//...
m.Use(session.Sessioner(session.Options{
    Provider:       "postgres",
    ProviderConfig: "user=a password=b host=localhost port=5432 dbname=c sslmode=disable",
}))
//...
```

### MySQL

Use following SQL to create database:

```sql
CREATE TABLE `session` (
    `key`       CHAR(16) NOT NULL,
    `data`      BLOB,
    `expiry`    INT(11) UNSIGNED NOT NULL,
    PRIMARY KEY (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
```

```go
import _ "github.com/go-macaron/session/mysql"

//...
m.Use(session.Sessioner(session.Options{
    Provider:       "mysql",
    ProviderConfig: "username:password@protocol(address)/dbname?param=value",
}))
//...
```

### Couchbase

```go
import _ "github.com/go-macaron/session/couchbase"

//...
m.Use(session.Sessioner(session.Options{
    Provider:       "couchbase",
    ProviderConfig: "username:password@protocol(address)/dbname?param=value",
}))
//...
```

### Ledis

```go
import _ "github.com/go-macaron/session/ledis"

//...
m.Use(session.Sessioner(session.Options{
    Provider:       "ledis",
    ProviderConfig: "data_dir=./app.db,db=0",
}))
//...
```

### Nodb

```go
import _ "github.com/go-macaron/session/nodb"

//...
m.Use(session.Sessioner(session.Options{
    Provider:       "nodb",
    ProviderConfig: "data/cache.db",
}))
//...
```

## Implement Provider Interface

In case you need to have your own implementation of session storage and provider, you can implement following two interfaces and take **memory** provider as a study example.

```go
// RawStore is the interface that operates the session data.
type RawStore interface {
    // Set sets value to given key in session.
    Set(key, value interface{}) error
    // Get gets value by given key in session.
    Get(key interface{}) interface{}
    // Delete deletes a key from session.
    Delete(key interface{}) error
    // ID returns current session ID.
    ID() string
    // Release releases session resource and save data to provider.
    Release() error
    // Flush deletes all session data.
    Flush() error
}

// Provider is the interface that provides session manipulations.
type Provider interface {
    // Init initializes session provider.
    Init(gclifetime int64, config string) error
    // Read returns raw session store by session ID.
    Read(sid string) (RawStore, error)
    // Exist returns true if session with given ID exists.
    Exist(sid string) bool
    // Destory deletes a session by session ID.
    Destory(sid string) error
    // Regenerate regenerates a session store from old session ID to new one.
    Regenerate(oldsid, sid string) (RawStore, error)
    // Count counts and returns number of sessions.
    Count() int
    // GC calls GC to clean expired sessions.
    GC()
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://go-macaron.com/middlewares/session.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
