oauth

package module
v0.0.0-...-dcdf285 Latest Latest
Warning

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

Go to latest
Published: Sep 21, 2015 License: MIT Imports: 13 Imported by: 0

README

OAuth 1.0 Library for Go

GoDoc

(If you need an OAuth 2.0 library, check out: http://code.google.com/p/goauth2/)

Developing your own apps, with this library

  • First, install the library

      go get github.com/mrjones/oauth
    
  • Then, check out the comments in oauth.go

  • Or, have a look at the examples:

    • Netflix

        go run examples/netflix/netflix.go --consumerkey [key] --consumersecret [secret] --appname [appname]
      
    • Twitter

      Command line:

        go run examples/twitter/twitter.go --consumerkey [key] --consumersecret [secret]
      

      Or, in the browser (using an HTTP server):

        go run examples/twitterserver/twitterserver.go --consumerkey [key] --consumersecret [secret] --port 8888        
      
    • The Google Latitude example is broken, now that Google uses OAuth 2.0

Contributing to this library

  • Please install the pre-commit hook, which will run tests, and go-fmt before committing.

      ln -s $PWD/pre-commit.sh .git/hooks/pre-commit
    
  • Running tests and building is as you'd expect:

      go test *.go
      go build *.go
    

Documentation

Overview

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-SHA1 signatures.
  • 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 "Get" using the AccessToken from step 7 to access protected resources.

Index

Constants

View Source
const (
	OAUTH_VERSION    = "1.0"
	SIGNATURE_METHOD = "HMAC-SHA1"

	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

This section is empty.

Functions

This section is empty.

Types

type AccessToken

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

type Consumer

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

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

Creates a new Consumer instance.

  • 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 (*Consumer) AuthorizeToken

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) BaseParams

func (c *Consumer) BaseParams(consumerKey string, additionalParams map[string]string) *OrderedParams

func (*Consumer) Debug

func (c *Consumer) Debug(enabled bool)

func (*Consumer) Delete

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

func (*Consumer) Get

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

func (*Consumer) GetAuthParamsForURL

func (c *Consumer) GetAuthParamsForURL(url string, userParams map[string]string, token *AccessToken) string

func (*Consumer) GetBaseParams

func (c *Consumer) GetBaseParams() *OrderedParams

func (*Consumer) GetRequestTokenAndUrl

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) Post

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

func (*Consumer) PostForm

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

DEPRECATED: Use Post() instead.

func (*Consumer) Put

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

func (*Consumer) RefreshToken

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 DataLocation

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

type HTTPExecuteError

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

func (e HTTPExecuteError) Error() string

Error provides a printable string description of an HTTPExecuteError.

type HttpClient

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

type OrderedParams

type OrderedParams struct {
	AllParams map[string]string
	// contains filtered or unexported fields
}

func NewOrderedParams

func NewOrderedParams() *OrderedParams

func (*OrderedParams) Add

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

func (*OrderedParams) AddUnescaped

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

func (*OrderedParams) Clone

func (o *OrderedParams) Clone() *OrderedParams

func (*OrderedParams) Get

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

func (*OrderedParams) Keys

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

func (*OrderedParams) Len

func (o *OrderedParams) Len() int

func (*OrderedParams) Less

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

func (*OrderedParams) Swap

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

type RequestToken

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 SHA1Signer

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

func (*SHA1Signer) Debug

func (s *SHA1Signer) Debug(enabled bool)

func (*SHA1Signer) Sign

func (s *SHA1Signer) Sign(message string, key string) string

type ServiceProvider

type ServiceProvider struct {
	RequestTokenUrl   string
	AuthorizeTokenUrl string
	AccessTokenUrl    string
}

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

Directories

Path Synopsis
examples
latitude
THIS NO LONGER WORKS!! Latitude is using OAuth 2.0 now.
THIS NO LONGER WORKS!! Latitude is using OAuth 2.0 now.
netflix
go run examples/netflix/netflix.go --consumerkey <key> --consumersecret <secret> --appname <appname>
go run examples/netflix/netflix.go --consumerkey <key> --consumersecret <secret> --appname <appname>
twitterserver
Similar to the twitter example, but using an HTTP server instead of the command line.
Similar to the twitter example, but using an HTTP server instead of the command line.

Jump to

Keyboard shortcuts

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