gogmagog/tokens/middleware.go
Deepak c1ae0706f9
All checks were successful
gitea-deepak/gogmagog/pipeline/head This commit looks good
Route now gets user ID from context with custom middleware
2021-01-17 17:33:40 -06:00

72 lines
1.9 KiB
Go

package tokens
import (
"context"
"fmt"
"log"
"net/http"
"strings"
)
type contextKey struct {
name string
}
var userIDCtxKey = &contextKey{"UserID"}
func unauthorized(w http.ResponseWriter, r *http.Request) {
code := http.StatusUnauthorized
http.Error(w, http.StatusText(code), code)
}
// TokenFromHeader tries to retreive the token string from the
// "Authorization" reqeust header: "Authorization: BEARER T".
func TokenFromHeader(r *http.Request) string {
// Get token from authorization header.
bearer := r.Header.Get("Authorization")
if len(bearer) > 7 && strings.ToUpper(bearer[0:6]) == "BEARER" {
return bearer[7:]
}
return ""
}
func (tok *jwtToker) Authenticator(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tokenString := TokenFromHeader(r)
if tokenString == "" {
log.Print("No valid token found")
unauthorized(w, r)
return
}
userID, err := tok.DecodeTokenString(tokenString)
if err != nil {
log.Printf("Error while verifying token: %s", err)
unauthorized(w, r)
return
}
log.Printf("Got user with ID: [%d]", userID)
ctx := context.WithValue(r.Context(), userIDCtxKey, userID)
// Authenticated
next.ServeHTTP(w, r.WithContext(ctx))
})
}
// GetUserID is a convenience method that gets the user ID from the context.
// I hate the fact that we're passing user ID on the context, but it is more
// idiomatic Go than any type shenanigans.
func GetUserID(ctx context.Context) (int, error) {
userID, ok := ctx.Value(userIDCtxKey).(int64)
if !ok {
return -1, fmt.Errorf("Could not parse user ID [%s] from context", ctx.Value(userIDCtxKey))
}
return int(userID), nil
}
// GetContextForUserID is a test helper method that creates a context with user ID set.
func GetContextForUserID(userID int) context.Context {
return context.WithValue(context.Background(), userIDCtxKey, int64(userID))
}