diff --git a/cmd/example-app/main.go b/cmd/example-app/main.go index ffa21c29ecb7a5dfcc1343850af3952690b1a048..3ec34e38bfcabe7fa9f8c2b0e851d4d8a4e20522 100644 --- a/cmd/example-app/main.go +++ b/cmd/example-app/main.go @@ -241,7 +241,7 @@ func (a *app) handleLogin(w http.ResponseWriter, r *http.Request) { authCodeURL := "" scopes = append(scopes, "openid", "profile", "email") - if r.FormValue("offline_acecss") != "yes" { + if r.FormValue("offline_access") != "yes" { authCodeURL = a.oauth2Config(scopes).AuthCodeURL(exampleAppState) } else if a.offlineAsScope { scopes = append(scopes, "offline_access") @@ -254,34 +254,42 @@ func (a *app) handleLogin(w http.ResponseWriter, r *http.Request) { } func (a *app) handleCallback(w http.ResponseWriter, r *http.Request) { - if errMsg := r.FormValue("error"); errMsg != "" { - http.Error(w, errMsg+": "+r.FormValue("error_description"), http.StatusBadRequest) - return - } - - if state := r.FormValue("state"); state != exampleAppState { - http.Error(w, fmt.Sprintf("expected state %q got %q", exampleAppState, state), http.StatusBadRequest) - return - } - - code := r.FormValue("code") - refresh := r.FormValue("refresh_token") var ( err error token *oauth2.Token ) oauth2Config := a.oauth2Config(nil) - switch { - case code != "": + switch r.Method { + case "GET": + // Authorization redirect callback from OAuth2 auth flow. + if errMsg := r.FormValue("error"); errMsg != "" { + http.Error(w, errMsg+": "+r.FormValue("error_description"), http.StatusBadRequest) + return + } + code := r.FormValue("code") + if code == "" { + http.Error(w, fmt.Sprintf("no code in request: %q", r.Form), http.StatusBadRequest) + return + } + if state := r.FormValue("state"); state != exampleAppState { + http.Error(w, fmt.Sprintf("expected state %q got %q", exampleAppState, state), http.StatusBadRequest) + return + } token, err = oauth2Config.Exchange(a.ctx, code) - case refresh != "": + case "POST": + // Form request from frontend to refresh a token. + refresh := r.FormValue("refresh_token") + if refresh == "" { + http.Error(w, fmt.Sprintf("no refresh_token in request: %q", r.Form), http.StatusBadRequest) + return + } t := &oauth2.Token{ RefreshToken: refresh, Expiry: time.Now().Add(-time.Hour), } token, err = oauth2Config.TokenSource(r.Context(), t).Token() default: - http.Error(w, fmt.Sprintf("no code in request: %q", r.Form), http.StatusBadRequest) + http.Error(w, fmt.Sprintf("method not implemented: %s", r.Method), http.StatusBadRequest) return } diff --git a/cmd/example-app/templates.go b/cmd/example-app/templates.go index c0f9dfbd84d262990a3d05514b432e1039618588..a870d0f0a9d699d7dfef20fea0a71fea66c4e538 100644 --- a/cmd/example-app/templates.go +++ b/cmd/example-app/templates.go @@ -8,7 +8,7 @@ import ( var indexTmpl = template.Must(template.New("index.html").Parse(`<html> <body> - <form action="/login"> + <form action="/login" method="post"> <p> Authenticate for:<input type="text" name="cross_client" placeholder="list of client-ids"> </p> @@ -50,8 +50,13 @@ pre { <body> <p> Token: <pre><code>{{ .IDToken }}</code></pre></p> <p> Claims: <pre><code>{{ .Claims }}</code></pre></p> + {{ if .RefreshToken }} <p> Refresh Token: <pre><code>{{ .RefreshToken }}</code></pre></p> - <p><a href="{{ .RedirectURL }}?refresh_token={{ .RefreshToken }}">Redeem refresh token</a><p> + <form action="{{ .RedirectURL }}" method="post"> + <input type="hidden" name="refresh_token" value="{{ .RefreshToken }}"> + <input type="submit" value="Redeem refresh token"> + </form> + {{ end }} </body> </html> `))