39 lines
1.1 KiB
Go
39 lines
1.1 KiB
Go
|
|
package auth
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"net/http"
|
||
|
|
)
|
||
|
|
|
||
|
|
type contextKey int
|
||
|
|
|
||
|
|
const claimsContextKey contextKey = iota
|
||
|
|
|
||
|
|
// RequireSession returns middleware that rejects a request with 401 unless
|
||
|
|
// it carries a valid SessionCookieName cookie signed with secret, and
|
||
|
|
// otherwise makes the session's Claims available via ClaimsFromContext.
|
||
|
|
func RequireSession(secret []byte) func(http.Handler) http.Handler {
|
||
|
|
return func(next http.Handler) http.Handler {
|
||
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
cookie, err := r.Cookie(SessionCookieName)
|
||
|
|
if err != nil {
|
||
|
|
http.Error(w, "not authenticated", http.StatusUnauthorized)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
claims, err := ParseSessionCookie(cookie, secret)
|
||
|
|
if err != nil {
|
||
|
|
http.Error(w, "not authenticated", http.StatusUnauthorized)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
next.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), claimsContextKey, claims)))
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ClaimsFromContext returns the authenticated user's Claims, as populated by
|
||
|
|
// RequireSession.
|
||
|
|
func ClaimsFromContext(ctx context.Context) (Claims, bool) {
|
||
|
|
c, ok := ctx.Value(claimsContextKey).(Claims)
|
||
|
|
return c, ok
|
||
|
|
}
|