oauth1

package module
v0.6.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 10, 2023 License: MIT Imports: 18 Imported by: 0

README

OAuth1 Build Status GoDoc

Package oauth1 provides a Go implementation of the OAuth 1 spec to allow end-users to authorize a client (i.e. consumer) to access protected resources on his/her behalf.

oauth1 takes design cues from golang.org/x/oauth2, to provide an analogous API and an http.Client with a Transport which signs/authorizes requests.

Install

go get github.com/dghubble/oauth1

Docs

Read GoDoc

Usage

Package oauth1 implements the OAuth1 authorization flow and provides an http.Client which can sign and authorize OAuth1 requests.

To implement "Login with X", use the gologin packages which provide login handlers for OAuth1 and OAuth2 providers.

To call the Twitter, Digits, or Tumblr OAuth1 APIs, use the higher level Go API clients.

Authorization Flow

Perform the OAuth 1 authorization flow to ask a user to grant an application access to his/her resources via an access token.

import (
    "github.com/dghubble/oauth1"
    "github.com/dghubble/oauth1/twitter""
)
...

config := oauth1.Config{
    ConsumerKey:    "consumerKey",
    ConsumerSecret: "consumerSecret",
    CallbackURL:    "http://mysite.com/oauth/twitter/callback",
    Endpoint:       twitter.AuthorizeEndpoint,
}
  1. When a user performs an action (e.g. "Login with X" button calls "/login" route) get an OAuth1 request token (temporary credentials).

    requestToken, requestSecret, err = config.RequestToken()
    // handle err
    
  2. Obtain authorization from the user by redirecting them to the OAuth1 provider's authorization URL to grant the application access.

    authorizationURL, err := config.AuthorizationURL(requestToken)
    // handle err
    http.Redirect(w, req, authorizationURL.String(), http.StatusFound)
    

    Receive the callback from the OAuth1 provider in a handler.

    requestToken, verifier, err := oauth1.ParseAuthorizationCallback(req)
    // handle err
    
  3. Acquire the access token (token credentials) which can later be used to make requests on behalf of the user.

    accessToken, accessSecret, err := config.AccessToken(requestToken, requestSecret, verifier)
    // handle error
    token := oauth1.NewToken(accessToken, accessSecret)
    

Check the examples to see this authorization flow in action from the command line, with Twitter PIN-based login and Tumblr login.

Authorized Requests

Use an access Token to make authorized requests on behalf of a user.

import (
    "github.com/dghubble/oauth1"
)

func main() {
    config := oauth1.NewConfig("consumerKey", "consumerSecret")
    token := oauth1.NewToken("token", "tokenSecret")

    // httpClient will automatically authorize http.Request's
    httpClient := config.Client(oauth1.NoContext, token)

    // example Twitter API request
    path := "https://api.twitter.com/1.1/statuses/home_timeline.json?count=2"
    resp, _ := httpClient.Get(path)
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Printf("Raw Response Body:\n%v\n", string(body))
}

Check the examples to see Twitter and Tumblr requests in action.

Concepts

An Endpoint groups an OAuth provider's token and authorization URL endpoints.Endpoints for common providers are provided in subpackages.

A Config stores a consumer application's consumer key and secret, the registered callback URL, and the Endpoint to which the consumer is registered. It provides OAuth1 authorization flow methods.

An OAuth1 Token is an access token which can be used to make signed requests on behalf of a user. See Authorized Requests for details.

If you've used the golang.org/x/oauth2 package for OAuth2 before, this organization should be familiar.

Contributing

See the Contributing Guide.

License

MIT License

Documentation

Overview

Package oauth1 is a Go implementation of the OAuth1 spec RFC 5849.

It allows end-users to authorize a client (consumer) to access protected resources on their behalf (e.g. login) and allows clients to make signed and authorized requests on behalf of a user (e.g. API calls).

It takes design cues from golang.org/x/oauth2, providing an http.Client which handles request signing and authorization.

Usage

Package oauth1 implements the OAuth1 authorization flow and provides an http.Client which can sign and authorize OAuth1 requests.

To implement "Login with X", use the https://github.com/dghubble/gologin packages which provide login handlers for OAuth1 and OAuth2 providers.

To call the Twitter, Digits, or Tumblr OAuth1 APIs, use the higher level Go API clients.

* https://github.com/dghubble/go-twitter * https://github.com/dghubble/go-digits * https://github.com/benfb/go-tumblr

Authorization Flow

Perform the OAuth 1 authorization flow to ask a user to grant an application access to his/her resources via an access token.

import (
	"github.com/dghubble/oauth1"
	"github.com/dghubble/oauth1/twitter""
)
...

config := oauth1.Config{
	ConsumerKey:    "consumerKey",
	ConsumerSecret: "consumerSecret",
	CallbackURL:    "http://mysite.com/oauth/twitter/callback",
	Endpoint:       twitter.AuthorizeEndpoint,
}

1. When a user performs an action (e.g. "Login with X" button calls "/login" route) get an OAuth1 request token (temporary credentials).

requestToken, requestSecret, err = config.RequestToken()
// handle err

2. Obtain authorization from the user by redirecting them to the OAuth1 provider's authorization URL to grant the application access.

authorizationURL, err := config.AuthorizationURL(requestToken)
// handle err
http.Redirect(w, req, authorizationURL.String(), htt.StatusFound)

Receive the callback from the OAuth1 provider in a handler.

requestToken, verifier, err := oauth1.ParseAuthorizationCallback(req)
// handle err

3. Acquire the access token (token credentials) which can later be used to make requests on behalf of the user.

accessToken, accessSecret, err := config.AccessToken(requestToken, requestSecret, verifier)
// handle error
token := oauth1.NewToken(accessToken, accessSecret)

Check the examples to see this authorization flow in action from the command line, with Twitter PIN-based login and Tumblr login.

Authorized Requests

Use an access Token to make authorized requests on behalf of a user.

import (
	"github.com/dghubble/oauth1"
)

func main() {
    config := oauth1.NewConfig("consumerKey", "consumerSecret")
    token := oauth1.NewToken("token", "tokenSecret")

    // httpClient will automatically authorize http.Request's
    httpClient := config.Client(token)

    // example Twitter API request
    path := "https://api.twitter.com/1.1/statuses/home_timeline.json?count=2"
    resp, _ := httpClient.Get(path)
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Printf("Raw Response Body:\n%v\n", string(body))
}

Check the examples to see Twitter and Tumblr requests in action.

Index

Constants

This section is empty.

Variables

View Source
var HTTPClient contextKey

HTTPClient is the context key to associate an *http.Client value with a context.

View Source
var NoContext = context.TODO()

NoContext is the default context to use in most cases.

Functions

func NewClient

func NewClient(ctx context.Context, config *Config, token *Token) *http.Client

NewClient returns a new http Client which signs requests via OAuth1.

func ParseAuthorizationCallback

func ParseAuthorizationCallback(req *http.Request) (requestToken, verifier string, err error)

ParseAuthorizationCallback parses an OAuth1 authorization callback request from a provider server. The oauth_token and oauth_verifier parameters are parsed to return the request token from earlier in the flow and the verifier string. See RFC 5849 2.2 Resource Owner Authorization.

func PercentEncode

func PercentEncode(input string) string

PercentEncode percent encodes a string according to RFC 3986 2.1.

func SignatureBase added in v0.6.4

func SignatureBase(req *http.Request, params map[string]string) string

SignatureBase combines the uppercase request method, percent encoded base string URI, and normalizes the request parameters int a parameter string. Returns the OAuth1 signature base string according to RFC5849 3.4.1.

func ValidateSignature added in v0.6.0

func ValidateSignature(ctx context.Context, req *http.Request, v ClientStorage) error

ValidateSignature checks that req contains a valid OAUTH 1 signature. It returns nil if the signature is valid, or an error if the validation fails.

Types

type ClientStorage added in v0.6.0

type ClientStorage = interface {
	// GetSigner returns the signer that should be used to validate the signature for a client.
	// To avoid timing attacks, GetSigner should return a Signer and a non-nil error
	// if the clientKey is invalid. ValidateRequest will still compute a signature
	// so that the runtime of ValidateRequest is about the same regardless of the clientKey's validity.
	// The http request is also available for additional validation, e.g. checking for HTTPS.
	GetSigner(ctx context.Context, clientKey, signatureMethod string, req *http.Request) (Signer, error)

	// ValidateNonce returns an error if a nonce has been used before.
	//
	// Per Section 3.3 of the spec:
	//    The timestamp value MUST be a positive integer.  Unless otherwise
	//    specified by the server's documentation, the timestamp is expressed
	//    in the number of seconds since January 1, 1970 00:00:00 GMT.
	//
	//    A nonce is a random string, uniquely generated by the client to allow
	//    the server to verify that a request has never been made before and
	//    helps prevent replay attacks when requests are made over a non-secure
	//    channel.  The nonce value MUST be unique across all requests with the
	//    same timestamp, client credentials, and token combinations.
	//
	//    To avoid the need to retain an infinite number of nonce values for
	//    future checks, servers MAY choose to restrict the time period after
	//    which a request with an old timestamp is rejected.  Note that this
	//    restriction implies a level of synchronization between the client's
	//    and server's clocks.
	ValidateNonce(ctx context.Context, clientKey, nonce string, timestamp int64, req *http.Request) error
}

ClientStorage represents an OAuth 1 provider's database of clients.

type Config

type Config struct {
	// Consumer Key (Client Identifier)
	ConsumerKey string
	// Consumer Secret (Client Shared-Secret)
	ConsumerSecret string
	// Callback URL
	CallbackURL string
	// Provider Endpoint specifying OAuth1 endpoint URLs
	Endpoint Endpoint
	// Realm of authorization
	Realm string
	// OAuth1 Signer (defaults to HMAC-SHA1)
	Signer Signer
}

Config represents an OAuth1 consumer's (client's) key and secret, the callback URL, and the provider Endpoint to which the consumer corresponds.

func NewConfig

func NewConfig(consumerKey, consumerSecret string) *Config

NewConfig returns a new Config with the given consumer key and secret.

func (*Config) AccessToken

func (c *Config) AccessToken(requestToken, requestSecret, verifier string) (accessToken, accessSecret string, err error)

AccessToken obtains an access token (token credential) by POSTing a request (with oauth_token and oauth_verifier in the auth header) to the Endpoint AccessTokenURL. Returns the access token and secret (token credentials). See RFC 5849 2.3 Token Credentials.

func (*Config) AuthorizationURL

func (c *Config) AuthorizationURL(requestToken string) (*url.URL, error)

AuthorizationURL accepts a request token and returns the *url.URL to the Endpoint's authorization page that asks the user (resource owner) for to authorize the consumer to act on his/her/its behalf. See RFC 5849 2.2 Resource Owner Authorization.

func (*Config) Client

func (c *Config) Client(ctx context.Context, t *Token) *http.Client

Client returns an HTTP client which uses the provided ctx and access Token.

func (*Config) RequestToken

func (c *Config) RequestToken() (requestToken, requestSecret string, err error)

RequestToken obtains a Request token and secret (temporary credential) by POSTing a request (with oauth_callback in the auth header) to the Endpoint RequestTokenURL. The response body form is validated to ensure oauth_callback_confirmed is true. Returns the request token and secret (temporary credentials). See RFC 5849 2.1 Temporary Credentials.

func (*Config) SignForm added in v0.6.5

func (c *Config) SignForm(method, url string, data url.Values, accessToken *Token) error

SignForm adds the oauth params and signature to data.

type Endpoint

type Endpoint struct {
	// Request URL (Temporary Credential Request URI)
	RequestTokenURL string
	// Authorize URL (Resource Owner Authorization URI)
	AuthorizeURL string
	// Access Token URL (Token Request URI)
	AccessTokenURL string
}

Endpoint represents an OAuth1 provider's (server's) request token, owner authorization, and access token request URLs.

type HMACSigner added in v0.4.0

type HMACSigner struct {
	ConsumerSecret string
}

HMACSigner signs messages with an HMAC SHA1 digest, using the concatenated consumer secret and token secret as the key.

func (*HMACSigner) Name added in v0.4.0

func (s *HMACSigner) Name() string

Name returns the HMAC-SHA1 method.

func (*HMACSigner) Sign added in v0.4.0

func (s *HMACSigner) Sign(tokenSecret, message string) (string, error)

Sign creates a concatenated consumer and token secret key and calculates the HMAC digest of the message. Returns the base64 encoded digest bytes.

type RSASigner added in v0.4.0

type RSASigner struct {
	PrivateKey *rsa.PrivateKey
}

RSASigner RSA PKCS1-v1_5 signs SHA1 digests of messages using the given RSA private key.

func (*RSASigner) Name added in v0.4.0

func (s *RSASigner) Name() string

Name returns the RSA-SHA1 method.

func (*RSASigner) Sign added in v0.4.0

func (s *RSASigner) Sign(tokenSecret, message string) (string, error)

Sign uses RSA PKCS1-v1_5 to sign a SHA1 digest of the given message. The tokenSecret is not used with this signing scheme.

type Signer

type Signer interface {
	// Name returns the name of the signing method.
	Name() string
	// Sign signs the message using the given secret key.
	Sign(key string, message string) (string, error)
}

A Signer signs messages to create signed OAuth1 Requests.

type Token

type Token struct {
	Token       string
	TokenSecret string
}

Token is an AccessToken (token credential) which allows a consumer (client) to access resources from an OAuth1 provider server.

func NewToken

func NewToken(token, tokenSecret string) *Token

NewToken returns a new Token with the given token and token secret.

type TokenSource

type TokenSource interface {
	Token() (*Token, error)
}

A TokenSource can return a Token.

func StaticTokenSource

func StaticTokenSource(token *Token) TokenSource

StaticTokenSource returns a TokenSource which always returns the same Token. This is appropriate for tokens which do not have a time expiration.

type Transport

type Transport struct {
	// Base is the base RoundTripper used to make HTTP requests. If nil, then
	// http.DefaultTransport is used
	Base http.RoundTripper
	// contains filtered or unexported fields
}

Transport is an http.RoundTripper which makes OAuth1 HTTP requests. It wraps a base RoundTripper and adds an Authorization header using the token from a TokenSource.

Transport is a low-level component, most users should use Config to create an http.Client instead.

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip authorizes the request with a signed OAuth1 Authorization header using the auther and TokenSource.

Directories

Path Synopsis
Package dropbox provides constants for using OAuth1 to access Dropbox.
Package dropbox provides constants for using OAuth1 to access Dropbox.
Package tumblr provides constants for using OAuth 1 to access Tumblr.
Package tumblr provides constants for using OAuth 1 to access Tumblr.
Package twitter provides constants for using OAuth1 to access Twitter.
Package twitter provides constants for using OAuth1 to access Twitter.
Package xing provides constants for using OAuth1 to access Xing.
Package xing provides constants for using OAuth1 to access Xing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL