go-twitch/auth/authorize.go

96 lines
3.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package auth
import (
"net/http"
"net/url"
"github.com/google/go-querystring/query"
)
type AuthorizeParams struct {
// A string-encoded JSON object that specifies the claims to include in the ID token.
// For information about claims, see Requesting claims: https://dev.twitch.tv/docs/authentication/getting-tokens-oidc/#requesting-claims
//
// Only used for OIDC auth flows
Claims *Claims `url:"claims,omitempty"`
// Set to true to force the user to re-authorize your apps access to their resources.
// The default is false.
ForceVerify *bool `url:"force_verify,omitempty"`
// Although optional, you are strongly encouraged to pass a nonce string to help
// prevent Cross-Site Request Forgery (CSRF) attacks. The server returns this string
// to you in the ID tokens list of claims. If this string doesnt match the nonce
// string that you passed, ignore the response. The nonce string should be randomly
// generated and unique for each OAuth request.
//
// Only used for OIDC auth flows
Nonce *string `url:"nonce,omitempty"`
// Must be set to code for Authorization code grant flow.
// Recommended for Server-to-Server flows. (with backend)
//
// Must be set to token for Implicit grant flow.
// Recommended for Client-to-Server flows. (no backend)
ResponseType string `url:"response_type"`
// A space-delimited list of scopes. The APIs that youre calling identify the
// scopes you must list. The list must include the openid scope. Dont forget to
// URL encode the list.
Scope []Scope `url:"scope,space"`
// Although optional, you are strongly encouraged to pass a state string to help
// prevent Cross-Site Request Forgery (CSRF) attacks. The server returns this string
// to you in your redirect URI (see the state parameter in the fragment portion of
// the URI). If this string doesnt match the state string that you passed, ignore
// the response. The state string should be randomly generated and unique for each
// OAuth request.
State *string `url:"state,omitempty"`
}
const AuthorizeUrl = "https://id.twitch.tv/oauth2/authorize"
// AuthorizeUrl returns the URL to redirect the user to for authorization.
func (c *Client) AuthorizeUrl(params *AuthorizeParams) *url.URL {
v, _ := query.Values(params)
v.Set("client_id", c.clientId)
v.Set("redirect_uri", c.redirectUri)
url, _ := url.Parse(AuthorizeUrl)
url.RawQuery = v.Encode()
return url
}
type AuthorizeHandler struct {
client *Client
scopes []Scope
}
var _ http.Handler = (*AuthorizeHandler)(nil)
// AuthorizeHandler returns an http.Handler that redirects the user to the
// authorization URL.
func (c *Client) AuthorizeHandler(scopes []Scope) http.Handler {
return &AuthorizeHandler{
client: c,
scopes: scopes,
}
}
// ServeHTTP implements http.Handler.
func (h *AuthorizeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
state := GenerateState()
if err := h.client.stateStorage.Save(w, state); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
url := h.client.AuthorizeUrl(&AuthorizeParams{
ResponseType: "code",
Scope: h.scopes,
State: &state,
})
http.Redirect(w, r, url.String(), http.StatusFound)
}