Created
February 17, 2020 10:20
-
-
Save mmitou/d6f6cb84aac1339fc23dc9e7df2821fd to your computer and use it in GitHub Desktop.
sample: OAuth2 protected resource server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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