82 lines
2.0 KiB
Go
82 lines
2.0 KiB
Go
package oauth2
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
// DefaultCookieName is the name of the stored cookie
|
|
DefaultCookieName = "session"
|
|
)
|
|
|
|
var _ Authenticator = &cookie{}
|
|
|
|
// cookie represents the location and expiration time of new cookies.
|
|
type cookie struct {
|
|
Name string
|
|
Duration time.Duration
|
|
Now func() time.Time
|
|
Tokens Tokenizer
|
|
}
|
|
|
|
// NewCookieJWT creates an Authenticator that uses cookies for auth
|
|
func NewCookieJWT(secret string, duration time.Duration) Authenticator {
|
|
return &cookie{
|
|
Name: DefaultCookieName,
|
|
Duration: duration,
|
|
Now: time.Now,
|
|
Tokens: &JWT{
|
|
Secret: secret,
|
|
Now: time.Now,
|
|
},
|
|
}
|
|
}
|
|
|
|
// Validate returns Principal of the Cookie if the Token is valid.
|
|
func (c *cookie) Validate(ctx context.Context, r *http.Request) (Principal, error) {
|
|
cookie, err := r.Cookie(c.Name)
|
|
if err != nil {
|
|
return Principal{}, ErrAuthentication
|
|
}
|
|
return c.Tokens.ValidPrincipal(ctx, Token(cookie.Value), c.Duration)
|
|
}
|
|
|
|
// Authorize will create cookies containing token information. It'll create
|
|
// a token with cookie.Duration of life to be stored as the cookie's value.
|
|
func (c *cookie) Authorize(ctx context.Context, w http.ResponseWriter, p Principal) error {
|
|
token, err := c.Tokens.Create(ctx, p, c.Duration)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Cookie has a Token baked into it
|
|
cookie := http.Cookie{
|
|
Name: DefaultCookieName,
|
|
Value: string(token),
|
|
HttpOnly: true,
|
|
Path: "/",
|
|
}
|
|
|
|
// Only set a cookie to be persistent (endure beyond the browser session)
|
|
// if auth duration is greater than zero
|
|
if c.Duration > 0 {
|
|
cookie.Expires = c.Now().UTC().Add(c.Duration)
|
|
}
|
|
|
|
http.SetCookie(w, &cookie)
|
|
return nil
|
|
}
|
|
|
|
// Expire returns a cookie that will expire an existing cookie
|
|
func (c *cookie) Expire(w http.ResponseWriter) {
|
|
cookie := http.Cookie{
|
|
Name: DefaultCookieName,
|
|
Value: "none",
|
|
HttpOnly: true,
|
|
Path: "/",
|
|
Expires: c.Now().UTC().Add(-1 * time.Hour), // to expire cookie set the time in the past
|
|
}
|
|
http.SetCookie(w, &cookie)
|
|
}
|