More work on auth and req ctx

This commit is contained in:
Daniel J. Summers 2018-03-12 21:44:43 -05:00
parent d92ac4430e
commit b7406bd827
3 changed files with 21 additions and 7 deletions

2
.gitignore vendored
View File

@ -256,6 +256,6 @@ paket-files/
src/api/build src/api/build
src/api/public/index.html src/api/public/index.html
src/api/public/static src/api/public/static
src/api/appsettings.json src/config.json
/build /build
src/*.exe src/*.exe

View File

@ -1,9 +1,11 @@
package routes package routes
import ( import (
"context"
"database/sql" "database/sql"
"fmt" "fmt"
"net/http" "net/http"
"time"
auth0 "github.com/auth0-community/go-auth0" auth0 "github.com/auth0-community/go-auth0"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
@ -17,14 +19,22 @@ type AuthConfig struct {
ClientSecret string `json:"secret"` ClientSecret string `json:"secret"`
} }
// DBHandler extends httprouter's handler with a DB instance // DBHandler extends httprouter's handler with a DB instance.
type DBHandler func(http.ResponseWriter, *http.Request, httprouter.Params, *sql.DB) type DBHandler func(http.ResponseWriter, *http.Request, httprouter.Params, *sql.DB)
//type APIHandler func(http.ResponseWriter, *http.Request, httprouter.Params, *sql.DB, string) //type APIHandler func(http.ResponseWriter, *http.Request, httprouter.Params, *sql.DB, string)
// ContextKey is the type of key used in our contexts.
type ContextKey string
// ContextUserKey is the key for the current user in the context.
const ContextUserKey ContextKey = "user"
func withDB(next DBHandler, db *sql.DB) httprouter.Handle { func withDB(next DBHandler, db *sql.DB) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
next(w, r, p, db) ctx, cancel := context.WithTimeout(context.Background(), time.Duration(60*time.Second))
defer cancel()
next(w, r.WithContext(ctx), p, db)
} }
} }
@ -32,9 +42,9 @@ func withAuth(next DBHandler, cfg *AuthConfig) DBHandler {
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params, db *sql.DB) { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params, db *sql.DB) {
secret := []byte(cfg.ClientSecret) secret := []byte(cfg.ClientSecret)
secretProvider := auth0.NewKeyProvider(secret) secretProvider := auth0.NewKeyProvider(secret)
audience := []string{"{YOUR-AUTH0-API-AUDIENCE}"} audience := []string{fmt.Sprintf("https://%s/userinfo", cfg.Domain)}
configuration := auth0.NewConfiguration(secretProvider, audience, fmt.Sprintf("https://%s.auth0.com/", cfg.Domain), jose.HS256) configuration := auth0.NewConfiguration(secretProvider, audience, fmt.Sprintf("https://%s/", cfg.Domain), jose.HS256)
validator := auth0.NewValidator(configuration) validator := auth0.NewValidator(configuration)
token, err := validator.ValidateRequest(r) token, err := validator.ValidateRequest(r)
@ -45,6 +55,11 @@ func withAuth(next DBHandler, cfg *AuthConfig) DBHandler {
w.WriteHeader(http.StatusUnauthorized) w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Unauthorized")) w.Write([]byte("Unauthorized"))
} else { } else {
values := make(map[string]interface{})
if err := token.Claims(secret, &values); err != nil {
sendError(w, r, err)
}
r = r.WithContext(context.WithValue(r.Context(), ContextUserKey, values["sub"]))
// TODO pass the user ID (sub) along; this -> doesn't work | r.Header.Add("user-id", token.Claims("sub")) // TODO pass the user ID (sub) along; this -> doesn't work | r.Header.Add("user-id", token.Claims("sub"))
next(w, r, p, db) next(w, r, p, db)
} }

View File

@ -30,9 +30,8 @@ func readSettings(f string) *Settings {
log.Fatal(err) log.Fatal(err)
} }
defer config.Close() defer config.Close()
parser := json.NewDecoder(config)
settings := Settings{} settings := Settings{}
if err = parser.Decode(&settings); err != nil { if err = json.NewDecoder(config).Decode(&settings); err != nil {
log.Fatal(err) log.Fatal(err)
} }
return &settings return &settings