oauth: github.com/mrjones/oauth Index | Files | Directories

package oauth

import "github.com/mrjones/oauth"

OAuth 1.0 consumer implementation. See http://www.oauth.net and RFC 5849

There are typically three parties involved in an OAuth exchange:

(1) The "Service Provider" (e.g. Google, Twitter, NetFlix) who operates the
    service where the data resides.
(2) The "End User" who owns that data, and wants to grant access to a third-party.
(3) That third-party who wants access to the data (after first being authorized by
    the user). This third-party is referred to as the "Consumer" in OAuth
    terminology.

This library is designed to help implement the third-party consumer by handling the low-level authentication tasks, and allowing for authenticated requests to the service provider on behalf of the user.

Caveats:

- Currently only supports HMAC and RSA signatures.
- Currently only supports SHA1 and SHA256 hashes.
- Currently only supports OAuth 1.0

Overview of how to use this library:

(1) First create a new Consumer instance with the NewConsumer function
(2) Get a RequestToken, and "authorization url" from GetRequestTokenAndUrl()
(3) Save the RequestToken, you will need it again in step 6.
(4) Redirect the user to the "authorization url" from step 2, where they will
    authorize your access to the service provider.
(5) Wait. You will be called back on the CallbackUrl that you provide, and you
    will recieve a "verification code".
(6) Call AuthorizeToken() with the RequestToken from step 2 and the
    "verification code" from step 5.
(7) You will get back an AccessToken.  Save this for as long as you need access
    to the user's data, and treat it like a password; it is a secret.
(8) You can now throw away the RequestToken from step 2, it is no longer
    necessary.
(9) Call "MakeHttpClient" using the AccessToken from step 7 to get an
    HTTP client which can access protected resources.

Index

Package Files

oauth.go provider.go

Constants

const (
    OAUTH_VERSION         = "1.0"
    SIGNATURE_METHOD_HMAC = "HMAC-"
    SIGNATURE_METHOD_RSA  = "RSA-"

    HTTP_AUTH_HEADER       = "Authorization"
    OAUTH_HEADER           = "OAuth "
    BODY_HASH_PARAM        = "oauth_body_hash"
    CALLBACK_PARAM         = "oauth_callback"
    CONSUMER_KEY_PARAM     = "oauth_consumer_key"
    NONCE_PARAM            = "oauth_nonce"
    SESSION_HANDLE_PARAM   = "oauth_session_handle"
    SIGNATURE_METHOD_PARAM = "oauth_signature_method"
    SIGNATURE_PARAM        = "oauth_signature"
    TIMESTAMP_PARAM        = "oauth_timestamp"
    TOKEN_PARAM            = "oauth_token"
    TOKEN_SECRET_PARAM     = "oauth_token_secret"
    VERIFIER_PARAM         = "oauth_verifier"
    VERSION_PARAM          = "oauth_version"
)

Variables

var HASH_METHOD_MAP = map[crypto.Hash]string{
    crypto.SHA1:   "SHA1",
    crypto.SHA256: "SHA256",
}

type AccessToken Uses

type AccessToken struct {
    Token          string
    Secret         string
    AdditionalData map[string]string
}

type ByValue Uses

type ByValue []string

func (ByValue) Len Uses

func (a ByValue) Len() int

func (ByValue) Less Uses

func (a ByValue) Less(i, j int) bool

func (ByValue) Swap Uses

func (a ByValue) Swap(i, j int)

type Consumer Uses

type Consumer struct {
    // Some ServiceProviders require extra parameters to be passed for various reasons.
    // For example Google APIs require you to set a scope= parameter to specify how much
    // access is being granted.  The proper values for scope= depend on the service:
    // For more, see: http://code.google.com/apis/accounts/docs/OAuth.html#prepScope
    AdditionalParams map[string]string

    // Some APIs (e.g. Netflix) aren't quite standard OAuth, and require passing
    // additional parameters when authorizing the request token. For most APIs
    // this field can be ignored.  For Netflix, do something like:
    // 	consumer.AdditionalAuthorizationUrlParams = map[string]string{
    // 		"application_name":   "YourAppName",
    // 		"oauth_consumer_key": "YourConsumerKey",
    // 	}
    AdditionalAuthorizationUrlParams map[string]string

    // Defaults to http.Client{}, can be overridden (e.g. for testing) as necessary
    HttpClient HttpClient

    // Some APIs (e.g. Intuit/Quickbooks) require sending additional headers along with
    // requests. (like "Accept" to specify the response type as XML or JSON) Note that this
    // will only *add* headers, not set existing ones.
    AdditionalHeaders map[string][]string
    // contains filtered or unexported fields
}

Consumers are stateless, you can call the various methods (GetRequestTokenAndUrl, AuthorizeToken, and Get) on various different instances of Consumers *as long as they were set up in the same way.* It is up to you, as the caller to persist the necessary state (RequestTokens and AccessTokens).

func NewConsumer Uses

func NewConsumer(consumerKey string, consumerSecret string,
    serviceProvider ServiceProvider) *Consumer

Creates a new Consumer instance, with a HMAC-SHA1 signer

- consumerKey and consumerSecret:
  values you should obtain from the ServiceProvider when you register your
  application.

- serviceProvider:
  see the documentation for ServiceProvider for how to create this.

func NewCustomConsumer Uses

func NewCustomConsumer(consumerKey string, consumerSecret string,
    hashFunc crypto.Hash, serviceProvider ServiceProvider,
    httpClient *http.Client) *Consumer

Creates a new Consumer instance, with a HMAC signer

- consumerKey and consumerSecret:
  values you should obtain from the ServiceProvider when you register your
  application.

- hashFunc:
  the crypto.Hash to use for signatures

- serviceProvider:
  see the documentation for ServiceProvider for how to create this.

- httpClient:
  Provides a custom implementation of the httpClient used under the hood
  to make the request.  This is especially useful if you want to use
  Google App Engine. Can be nil for default.

func NewCustomHttpClientConsumer Uses

func NewCustomHttpClientConsumer(consumerKey string, consumerSecret string,
    serviceProvider ServiceProvider, httpClient *http.Client) *Consumer

Creates a new Consumer instance, with a HMAC-SHA1 signer

     - consumerKey and consumerSecret:
       values you should obtain from the ServiceProvider when you register your
       application.

     - serviceProvider:
       see the documentation for ServiceProvider for how to create this.

		- httpClient:
		  Provides a custom implementation of the httpClient used under the hood
		  to make the request.  This is especially useful if you want to use
		  Google App Engine.

func NewCustomRSAConsumer Uses

func NewCustomRSAConsumer(consumerKey string, privateKey *rsa.PrivateKey,
    hashFunc crypto.Hash, serviceProvider ServiceProvider,
    httpClient *http.Client) *Consumer

Creates a new Consumer instance, with a RSA signer

- consumerKey:
  value you should obtain from the ServiceProvider when you register your
  application.

- privateKey:
  the private key to use for signatures

- hashFunc:
  the crypto.Hash to use for signatures

- serviceProvider:
  see the documentation for ServiceProvider for how to create this.

- httpClient:
  Provides a custom implementation of the httpClient used under the hood
  to make the request.  This is especially useful if you want to use
  Google App Engine. Can be nil for default.

func NewRSAConsumer Uses

func NewRSAConsumer(consumerKey string, privateKey *rsa.PrivateKey,
    serviceProvider ServiceProvider) *Consumer

Creates a new Consumer instance, with a RSA-SHA1 signer

- consumerKey:
  value you should obtain from the ServiceProvider when you register your
  application.

- privateKey:
  the private key to use for signatures

- serviceProvider:
  see the documentation for ServiceProvider for how to create this.

func (*Consumer) AuthorizeToken Uses

func (c *Consumer) AuthorizeToken(rtoken *RequestToken, verificationCode string) (atoken *AccessToken, err error)

After the user has authorized you to the service provider, use this method to turn your temporary RequestToken into a permanent AccessToken. You must pass in two values:

- rtoken:
  The RequestToken returned from GetRequestTokenAndUrl()

- verificationCode:
  The string which passed back from the server, either as the oauth_verifier
  query param appended to callbackUrl *OR* a string manually entered by the user
  if callbackUrl is "oob"

It will return:

- atoken:
  A permanent AccessToken which can be used to access the user's data (until it is
  revoked by the user or the service provider).

- err:
  Set only if there was an error, nil otherwise.

func (*Consumer) AuthorizeTokenWithParams Uses

func (c *Consumer) AuthorizeTokenWithParams(rtoken *RequestToken, verificationCode string, additionalParams map[string]string) (atoken *AccessToken, err error)

func (*Consumer) Debug Uses

func (c *Consumer) Debug(enabled bool)

func (*Consumer) Delete Uses

func (c *Consumer) Delete(url string, userParams map[string]string, token *AccessToken) (resp *http.Response, err error)

** DEPRECATED ** Please call "Delete" on the http client returned by MakeHttpClient instead

func (*Consumer) Get Uses

func (c *Consumer) Get(url string, userParams map[string]string, token *AccessToken) (resp *http.Response, err error)

** DEPRECATED ** Please call Get on the http client returned by MakeHttpClient instead!

Executes an HTTP Get, authorized via the AccessToken.

- url:
  The base url, without any query params, which is being accessed

- userParams:
  Any key=value params to be included in the query string

- token:
  The AccessToken returned by AuthorizeToken()

This method returns:

- resp:
  The HTTP Response resulting from making this request.

- err:
  Set only if there was an error, nil otherwise.

func (*Consumer) GetRequestTokenAndUrl Uses

func (c *Consumer) GetRequestTokenAndUrl(callbackUrl string) (rtoken *RequestToken, loginUrl string, err error)

Kicks off the OAuth authorization process.

- callbackUrl:
  Authorizing a token *requires* redirecting to the service provider. This is the
  URL which the service provider will redirect the user back to after that
  authorization is completed. The service provider will pass back a verification
  code which is necessary to complete the rest of the process (in AuthorizeToken).
  Notes on callbackUrl:
    - Some (all?) service providers allow for setting "oob" (for out-of-band) as a
      callback url.  If this is set the service provider will present the
      verification code directly to the user, and you must provide a place for
      them to copy-and-paste it into.
    - Otherwise, the user will be redirected to callbackUrl in the browser, and
      will append a "oauth_verifier=<verifier>" parameter.

This function returns:

- rtoken:
  A temporary RequestToken, used during the authorization process. You must save
  this since it will be necessary later in the process when calling
  AuthorizeToken().

- url:
  A URL that you should redirect the user to in order that they may authorize you
  to the service provider.

- err:
  Set only if there was an error, nil otherwise.

func (*Consumer) GetRequestTokenAndUrlWithParams Uses

func (c *Consumer) GetRequestTokenAndUrlWithParams(callbackUrl string, additionalParams map[string]string) (rtoken *RequestToken, loginUrl string, err error)

func (*Consumer) MakeHttpClient Uses

func (c *Consumer) MakeHttpClient(token *AccessToken) (*http.Client, error)

func (*Consumer) MakeRoundTripper Uses

func (c *Consumer) MakeRoundTripper(token *AccessToken) (*RoundTripper, error)

func (*Consumer) Post Uses

func (c *Consumer) Post(url string, userParams map[string]string, token *AccessToken) (resp *http.Response, err error)

** DEPRECATED ** Please call "Post" on the http client returned by MakeHttpClient instead

func (*Consumer) PostForm Uses

func (c *Consumer) PostForm(url string, userParams map[string]string, token *AccessToken) (resp *http.Response, err error)

** DEPRECATED ** Please call "Post" on the http client returned by MakeHttpClient instead

func (*Consumer) PostJson Uses

func (c *Consumer) PostJson(url string, body string, token *AccessToken) (resp *http.Response, err error)

** DEPRECATED ** Please call "Do" on the http client returned by MakeHttpClient instead (and set the "Content-Type" header explicitly in the http.Request)

func (*Consumer) PostMultipart Uses

func (c *Consumer) PostMultipart(url, multipartName string, multipartData io.ReadCloser, userParams map[string]string, token *AccessToken) (resp *http.Response, err error)

** DEPRECATED ** Please call "Do" on the http client returned by MakeHttpClient instead (and setup the multipart data explicitly in the http.Request)

func (*Consumer) PostWithBody Uses

func (c *Consumer) PostWithBody(url string, body string, userParams map[string]string, token *AccessToken) (resp *http.Response, err error)

** DEPRECATED ** Please call "Post" on the http client returned by MakeHttpClient instead

func (*Consumer) PostXML Uses

func (c *Consumer) PostXML(url string, body string, token *AccessToken) (resp *http.Response, err error)

** DEPRECATED ** Please call "Do" on the http client returned by MakeHttpClient instead (and set the "Content-Type" header explicitly in the http.Request)

func (*Consumer) Put Uses

func (c *Consumer) Put(url string, body string, userParams map[string]string, token *AccessToken) (resp *http.Response, err error)

** DEPRECATED ** Please call "Put" on the http client returned by MakeHttpClient instead

func (*Consumer) RefreshToken Uses

func (c *Consumer) RefreshToken(accessToken *AccessToken) (atoken *AccessToken, err error)

Use the service provider to refresh the AccessToken for a given session. Note that this is only supported for service providers that manage an authorization session (e.g. Yahoo).

Most providers do not return the SESSION_HANDLE_PARAM needed to refresh the token.

See http://oauth.googlecode.com/svn/spec/ext/session/1.0/drafts/1/spec.html for more information.

- accessToken:
  The AccessToken returned from AuthorizeToken()

It will return:

- atoken:
  An AccessToken which can be used to access the user's data (until it is
  revoked by the user or the service provider).

- err:
  Set if accessToken does not contain the SESSION_HANDLE_PARAM needed to
  refresh the token, or if an error occurred when making the request.

type ConsumerGetter Uses

type ConsumerGetter func(key string, header map[string]string) (*Consumer, error)

type DataLocation Uses

type DataLocation int
const (
    LOC_BODY DataLocation = iota + 1
    LOC_URL
    LOC_MULTIPART
    LOC_JSON
    LOC_XML
)

type HMACSigner Uses

type HMACSigner struct {
    // contains filtered or unexported fields
}

func (*HMACSigner) Debug Uses

func (s *HMACSigner) Debug(enabled bool)

func (*HMACSigner) HashFunc Uses

func (s *HMACSigner) HashFunc() crypto.Hash

func (*HMACSigner) Sign Uses

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

func (*HMACSigner) SignatureMethod Uses

func (s *HMACSigner) SignatureMethod() string

func (*HMACSigner) Verify Uses

func (s *HMACSigner) Verify(message string, signature string) error

type HTTPExecuteError Uses

type HTTPExecuteError struct {
    // RequestHeaders provides a stringified listing of request headers.
    RequestHeaders string
    // ResponseBodyBytes is the response read into a byte slice.
    ResponseBodyBytes []byte
    // Status is the status code string response.
    Status string
    // StatusCode is the parsed status code.
    StatusCode int
}

HTTPExecuteError signals that a call to httpExecute failed.

func (HTTPExecuteError) Error Uses

func (e HTTPExecuteError) Error() string

Error provides a printable string description of an HTTPExecuteError.

type HttpClient Uses

type HttpClient interface {
    Do(req *http.Request) (resp *http.Response, err error)
}

type OrderedParams Uses

type OrderedParams struct {
    // contains filtered or unexported fields
}

func NewOrderedParams Uses

func NewOrderedParams() *OrderedParams

func (*OrderedParams) Add Uses

func (o *OrderedParams) Add(key, value string)

func (*OrderedParams) AddUnescaped Uses

func (o *OrderedParams) AddUnescaped(key, value string)

func (*OrderedParams) Clone Uses

func (o *OrderedParams) Clone() *OrderedParams

func (*OrderedParams) Get Uses

func (o *OrderedParams) Get(key string) []string

func (*OrderedParams) Keys Uses

func (o *OrderedParams) Keys() []string

func (*OrderedParams) Len Uses

func (o *OrderedParams) Len() int

func (*OrderedParams) Less Uses

func (o *OrderedParams) Less(i int, j int) bool

func (*OrderedParams) Swap Uses

func (o *OrderedParams) Swap(i int, j int)

type Provider Uses

type Provider struct {
    ConsumerGetter ConsumerGetter
    // contains filtered or unexported fields
}

Provider provides methods for a 2-legged Oauth1 provider

func NewProvider Uses

func NewProvider(secretGetter ConsumerGetter) *Provider

NewProvider takes a function to get the consumer secret from a datastore. Returns a Provider

func (*Provider) IsAuthorized Uses

func (provider *Provider) IsAuthorized(request *http.Request) (*string, error)

IsAuthorized takes an *http.Request and returns a pointer to a string containing the consumer key, or nil if not authorized

type RSASigner Uses

type RSASigner struct {
    // contains filtered or unexported fields
}

func (*RSASigner) Debug Uses

func (s *RSASigner) Debug(enabled bool)

func (*RSASigner) HashFunc Uses

func (s *RSASigner) HashFunc() crypto.Hash

func (*RSASigner) Sign Uses

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

func (*RSASigner) SignatureMethod Uses

func (s *RSASigner) SignatureMethod() string

func (*RSASigner) Verify Uses

func (s *RSASigner) Verify(message string, base64signature string) error

type RequestToken Uses

type RequestToken struct {
    Token  string
    Secret string
}

TODO(mrjones) Do we definitely want separate "Request" and "Access" token classes? They're identical structurally, but used for different purposes.

type RoundTripper Uses

type RoundTripper struct {
    // contains filtered or unexported fields
}

func (*RoundTripper) RoundTrip Uses

func (rt *RoundTripper) RoundTrip(userRequest *http.Request) (*http.Response, error)

type ServiceProvider Uses

type ServiceProvider struct {
    RequestTokenUrl   string
    AuthorizeTokenUrl string
    AccessTokenUrl    string
    HttpMethod        string
    BodyHash          bool
    IgnoreTimestamp   bool

    // Enables non spec-compliant behavior:
    // Allow parameters to be passed in the query string rather
    // than the body.
    // See https://github.com/mrjones/oauth/pull/63
    SignQueryParams bool
}

Information about how to contact the service provider (see #1 above). You usually find all of these URLs by reading the documentation for the service that you're trying to connect to. Some common examples are:

(1) Google, standard APIs:
    http://code.google.com/apis/accounts/docs/OAuth_ref.html
    - RequestTokenUrl:   https://www.google.com/accounts/OAuthGetRequestToken
    - AuthorizeTokenUrl: https://www.google.com/accounts/OAuthAuthorizeToken
    - AccessTokenUrl:    https://www.google.com/accounts/OAuthGetAccessToken
    Note: Some Google APIs (for example, Google Latitude) use different values for
    one or more of those URLs.
(2) Twitter API:
    http://dev.twitter.com/pages/auth
    - RequestTokenUrl:   http://api.twitter.com/oauth/request_token
    - AuthorizeTokenUrl: https://api.twitter.com/oauth/authorize
    - AccessTokenUrl:    https://api.twitter.com/oauth/access_token
(3) NetFlix API:
    http://developer.netflix.com/docs/Security
    - RequestTokenUrl:   http://api.netflix.com/oauth/request_token
    - AuthroizeTokenUrl: https://api-user.netflix.com/oauth/login
    - AccessTokenUrl:    http://api.netflix.com/oauth/access_token

Set HttpMethod if the service provider requires a different HTTP method to be used for OAuth token requests

Directories

PathSynopsis
examples/jiraNote: I haven't had a chance to test that this works.
examples/latitudeTHIS NO LONGER WORKS!! Latitude is using OAuth 2.0 now.
examples/netflixNOTE: Netflix shut down its API in 2014.
examples/trelloCheck Trello OAuth Detail At: https://trello.com/docs/gettingstarted/oauth.html
examples/trelloserverCheck Trello OAuth Detail At: https://trello.com/docs/gettingstarted/oauth.html
examples/twitter
examples/twitterserverSimilar to the twitter example, but using an HTTP server instead of the command line.
examples/twittersingleuser

Package oauth imports 20 packages (graph) and is imported by 224 packages. Updated 2018-06-30. Refresh now. Tools for package owners.