package auth import ( "fmt" "net/http" ) type CallbackHandler struct { client *Auth handler TokenHandler } var _ http.Handler = (*CallbackHandler)(nil) // CallbackHandler returns an http.Handler that handles callback responses // from the twitch authentication server. func (c *Auth) CallbackHandler(h TokenHandler) http.Handler { return &CallbackHandler{ client: c, handler: h, } } // ServeHTTP implements http.Handler. func (c *CallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { q := r.URL.Query() state := q.Get("state") if state == "" { http.Error(w, "state is empty", http.StatusBadRequest) return } storedState, err := c.client.stateStorage.Get(r) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if state != storedState { http.Error(w, "state mismatch", http.StatusBadRequest) return } if q.Has("error") { err := q.Get("error") desc := q.Get("error_description") errMsg := fmt.Sprintf("%s: %s", err, desc) http.Error(w, errMsg, http.StatusBadRequest) return } code := q.Get("code") scope := q.Get("scope") _ = scope token, err := c.client.GetTokenFromCode(r.Context(), code) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } c.handler.Handle(state, token.AccessToken) }