Documentation ¶
Overview ¶
Package oauth2 is a middleware that provides support of user login via an OAuth 2.0 backend for Macaron.
Example (JWT) ¶
package main import ( "log" "net/http" "github.com/macaron-contrib/oauth2" ) func main() { opts, err := oauth2.New( // The contents of your RSA private key or your PEM file // that contains a private key. // If you have a p12 file instead, you // can use `openssl` to export the private key into a pem file. // // $ openssl pkcs12 -in key.p12 -out key.pem -nodes // // It only supports PEM containers with no passphrase. oauth2.JWTClient( "xxx@developer.gserviceaccount.com", []byte("-----BEGIN RSA PRIVATE KEY-----...")), oauth2.Scope("SCOPE1", "SCOPE2"), oauth2.JWTEndpoint("https://provider.com/o/oauth2/token"), // If you would like to impersonate a user, you can // create a transport with a subject. The following GET // request will be made on the behalf of user@example.com. // Subject is optional. oauth2.Subject("user@example.com"), ) if err != nil { log.Fatal(err) } // Initiate an http.Client, the following GET request will be // authorized and authenticated on the behalf of user@example.com. client := http.Client{Transport: opts.NewTransport()} client.Get("...") }
Output:
Example (Regular) ¶
package main import ( "fmt" "log" "net/http" "github.com/macaron-contrib/oauth2" ) func main() { opts, err := oauth2.New( oauth2.Client("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET"), oauth2.RedirectURL("YOUR_REDIRECT_URL"), oauth2.Scope("SCOPE1", "SCOPE2"), oauth2.Endpoint( "https://provider.com/o/oauth2/auth", "https://provider.com/o/oauth2/token", ), ) if err != nil { log.Fatal(err) } // Redirect user to consent page to ask for permission // for the scopes specified above. url := opts.AuthCodeURL("state", "online", "auto") fmt.Printf("Visit the URL for the auth dialog: %v", url) // Use the authorization code that is pushed to the redirect URL. // NewTransportWithCode will do the handshake to retrieve // an access token and initiate a Transport that is // authorized and authenticated by the retrieved token. var code string if _, err = fmt.Scan(&code); err != nil { log.Fatal(err) } t, err := opts.NewTransportFromCode(code) if err != nil { log.Fatal(err) } // You can use t to initiate a new http.Client and // start making authenticated requests. client := http.Client{Transport: t} client.Get("...") }
Output:
Index ¶
- Constants
- Variables
- func Dropbox(opt Options) macaron.Handler
- func Facebook(opt Options) macaron.Handler
- func GitHub(opt Options) macaron.Handler
- func Google(opt Options) macaron.Handler
- func LinkedIn(opt Options) macaron.Handler
- func NewOAuth2Provider(option Options, authURL, tokenURL string) macaron.Handler
- func ParseKey(key []byte) (*rsa.PrivateKey, error)
- func Tencent(opt Options) macaron.Handler
- func Weibo(opt Options) macaron.Handler
- type Options
- func (o *Options) AuthCodeURL(state, accessType, prompt string) string
- func (o *Options) NewTransport() *Transport
- func (o *Options) NewTransportFromCode(code string) (*Transport, error)
- func (o *Options) NewTransportFromToken(t *Token) *Transport
- func (o *Options) NewTransportFromTokenStore(store TokenStore) (*Transport, error)
- type Token
- type TokenStore
- type Tokens
- type Transport
Examples ¶
Constants ¶
const ( KEY_TOKEN = "oauth2_token" KEY_NEXT_PAGE = "next" )
Variables ¶
var ( AppSubUrl string // PathLogin is the path to handle OAuth 2.0 logins. PathLogin = "/login" // PathLogout is the path to handle OAuth 2.0 logouts. PathLogout = "/logout" // PathCallback is the path to handle callback from OAuth 2.0 backend // to exchange credentials. PathCallback = "/oauth2callback" // PathError is the path to handle error cases. PathError = "/oauth2error" )
var LoginRequired macaron.Handler = func() macaron.Handler { return func(ctx *macaron.Context, s session.Store) { token := unmarshallToken(s) if token == nil || token.Expired() { next := url.QueryEscape(ctx.Req.URL.RequestURI()) ctx.Redirect(PathLogin + "?next=" + next) } } }()
Handler that redirects user to the login page if user is not logged in. Sample usage: m.Get("/login-required", oauth2.LoginRequired, func() ... {})
Functions ¶
func NewOAuth2Provider ¶
NewOAuth2Provider returns a generic OAuth 2.0 backend endpoint.
func ParseKey ¶
func ParseKey(key []byte) (*rsa.PrivateKey, error)
ParseKey converts the binary contents of a private key file to an *rsa.PrivateKey. It detects whether the private key is in a PEM container or not. If so, it extracts the the private key from PEM container before conversion. It only supports PEM containers with no passphrase.
Types ¶
type Options ¶
type Options struct { // ClientID is the OAuth client identifier used when communicating with // the configured OAuth provider. ClientID string // ClientSecret is the OAuth client secret used when communicating with // the configured OAuth provider. ClientSecret string PathLogin string PathLogout string PathCallback string // RedirectURL is the URL to which the user will be returned after // granting (or denying) access. RedirectURL string // Email is the OAuth client identifier used when communicating with // the configured OAuth provider. Email string // PrivateKey contains the contents of an RSA private key or the // contents of a PEM file that contains a private key. The provided // private key is used to sign JWT payloads. // PEM containers with a passphrase are not supported. // Use the following command to convert a PKCS 12 file into a PEM. // // $ openssl pkcs12 -in key.p12 -out key.pem -nodes // PrivateKey *rsa.PrivateKey // Scopes identify the level of access being requested. Subject string // Scopes optionally specifies a list of requested permission scopes. Scopes []string // AuthURL represents the authorization endpoint of the OAuth 2.0 provider. AuthURL *url.URL // TokenURL represents the token endpoint of the OAuth 2.0 provider. TokenURL *url.URL // AUD represents the token endpoint required to complete the 2-legged JWT flow. AUD *url.URL // TokenStore reads a token from the store and writes it back to the store // if a token refresh occurs. // Optional. TokenStore TokenStore TokenFetcherFunc func(t *Token) (*Token, error) Client *http.Client }
Options represents an object to keep the state of the OAuth 2.0 flow.
func New ¶
New builds a new options object and determines the type of the OAuth 2.0 (2-legged, 3-legged or custom) by looking at the provided options. If the flow type cannot determined automatically, an error is returned.
func (*Options) AuthCodeURL ¶
AuthCodeURL returns a URL to OAuth 2.0 provider's consent page that asks for permissions for the required scopes explicitly.
State is a token to protect the user from CSRF attacks. You must always provide a non-zero string and validate that it matches the the state query parameter on your redirect callback. See http://tools.ietf.org/html/rfc6749#section-10.12 for more info.
Access type is an OAuth extension that gets sent as the "access_type" field in the URL from AuthCodeURL. It may be "online" (default) or "offline". If your application needs to refresh access tokens when the user is not present at the browser, then use offline. This will result in your application obtaining a refresh token the first time your application exchanges an authorization code for a user.
Approval prompt indicates whether the user should be re-prompted for consent. If set to "auto" (default) the user will be prompted only if they haven't previously granted consent and the code can only be exchanged for an access token. If set to "force" the user will always be prompted, and the code can be exchanged for a refresh token.
func (*Options) NewTransport ¶
NewTransport returns a Transport.
func (*Options) NewTransportFromCode ¶
NewTransportFromCode exchanges the code to retrieve a new access token and returns an authorized and authenticated Transport.
func (*Options) NewTransportFromToken ¶
newTransportFromToken returns a new Transport that is authorized and authenticated with the provided token.
func (*Options) NewTransportFromTokenStore ¶
func (o *Options) NewTransportFromTokenStore(store TokenStore) (*Transport, error)
NewTransportFromTokenStore reads the token from the store and returns a Transport that is authorized and the authenticated by the returned token.
type Token ¶
type Token struct { // A token that authorizes and authenticates the requests. AccessToken string `json:"access_token"` // Identifies the type of token returned. TokenType string `json:"token_type,omitempty"` // A token that may be used to obtain a new access token. RefreshToken string `json:"refresh_token,omitempty"` // The remaining lifetime of the access token. Expiry time.Time `json:"expiry,omitempty"` // Raw optionally contains extra metadata from the server // when updating a token. Raw interface{} }
Token represents the crendentials used to authorize the requests to access protected resources on the OAuth 2.0 provider's backend.
type TokenStore ¶
type TokenStore interface { // ReadToken reads the token from the store. // If the read is successful, it should return the token and a nil error. // The returned tokens may be expired tokens. // If there is no token in the store, it should return a nil token and a nil error. // It should return a non-nil error when an unrecoverable failure occurs. ReadToken() (*Token, error) // WriteToken writes the token to the cache. WriteToken(*Token) }
TokenStore implementations read and write OAuth 2.0 tokens from a persistence layer.
type Tokens ¶
type Tokens interface { Access() string Refresh() string Expired() bool ExpiryTime() time.Time Extra(string) string }
Tokens represents a container that contains user's OAuth 2.0 access and refresh tokens.
type Transport ¶
type Transport struct {
// contains filtered or unexported fields
}
Transport is an http.RoundTripper that makes OAuth 2.0 HTTP requests.