Skip to content

Instantly share code, notes, and snippets.

@mmitou
Created February 17, 2020 10:20
Show Gist options
  • Select an option

  • Save mmitou/d6f6cb84aac1339fc23dc9e7df2821fd to your computer and use it in GitHub Desktop.

Select an option

Save mmitou/d6f6cb84aac1339fc23dc9e7df2821fd to your computer and use it in GitHub Desktop.
sample: OAuth2 protected resource server
package main
import (
"fmt"
"log"
"net/http"
"strings"
jwt "github.com/dgrijalva/jwt-go"
"github.com/gorilla/mux"
"github.com/lestrrat/go-jwx/jwk"
"golang.org/x/xerrors"
)
const (
jwksUri = "https://dev-ag9zx3un.auth0.com/.well-known/jwks.json"
)
func getKey(token *jwt.Token) (interface{}, error) {
jwks, err := jwk.FetchHTTP(jwksUri)
if err != nil {
xerr := xerrors.Errorf("jwk.FetchHTTP(%s) failed: %v", jwksUri, err)
return nil, xerr
}
keyID, ok := token.Header["kid"].(string)
if !ok {
xerr := xerrors.Errorf("type assertion failed. %+v", token.Header["kid"])
return nil, xerr
}
keys := jwks.LookupKeyID(keyID)
if len(keys) == 0 {
xerr := xerrors.Errorf("not found kid(%s) in jwks(%v)", keyID, jwks)
return nil, xerr
}
return keys[0].Materialize()
}
func JwtVerifyMiddleware(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
// Authorization headerからaccess tokenを取り出す
// もしaccess token が無いなら400 bad requestを返す
authHeader := r.Header.Get("authorization")
if authHeader == "" {
http.Error(w, "not found authorization header", http.StatusBadRequest)
return
}
authHeaderValues := strings.Split(authHeader, "Bearer")
if len(authHeaderValues) != 2 {
http.Error(w, "not found Bearer in authorization header", http.StatusBadRequest)
return
}
accessToken := strings.TrimSpace(authHeaderValues[1])
log.Print(accessToken)
// access tokenを検証する
// もし無効なaccess tokenなら401 unauthrizedを返す
_, err := jwt.Parse(accessToken, getKey)
if err != nil {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
// TODO: scope check
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
func Hello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello!")
}
func main() {
r := mux.NewRouter()
r.Use(JwtVerifyMiddleware)
r.HandleFunc("/", Hello)
srv := &http.Server{
Handler: r,
Addr: "127.0.0.1:8080",
}
log.Fatal(srv.ListenAndServe())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment