OAuth 1.0 implementation in go (golang).

Overview

OAuth 1.0 Library for Go

GoDoc

CircleCI

(If you need an OAuth 2.0 library, check out: https://godoc.org/golang.org/x/oauth2)

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
    
Issues
  • Would like to patch so that Oauth works with Yahoo. Preferred Way?

    Would like to patch so that Oauth works with Yahoo. Preferred Way?

    First, Thanks for making this excellent package.

    I recently had to edit the package itself locally to get it to work with Yahoo's Oauth. The reason is this:

    • Yahoo's tokens expire every hour.
    • To refresh you need an additional parameter, oauth_session_handle, which is sent in the response to the original AuthorizeToken token request. See here: http://developer.yahoo.com/oauth/guide/oauth-refreshaccesstoken.html

    The problem is that of course that this package's AuthorizeToken function throws away that response data. It was a fairly easy fix for my one off project. However, I'd like to submit a patch that would generalize the scenario of needing more of the body elements than just the Auth_tokens.

    What do you think the best form would be? What would you accept in a pull request? Thanks Matt

    Matt LeVeck

    opened by mleveck 8
  • Does this library work with one legged authorization?

    Does this library work with one legged authorization?

    If you're given 4 tokens straight away

    • consumer
    • consumer secret
    • access token
    • access token secret

    What order of functions do you use? Will oauth.NewConsumer() work without the request URLs?

    opened by trosel 7
  • The logic behind preventing multiple form parameters with same name.

    The logic behind preventing multiple form parameters with same name.

    https://github.com/mrjones/oauth/blob/78d64468d6ec7b74e4b0d47cf61b4f4e288b944b/oauth.go#L835

    I am creating an application that makes authorized request to following endpoint. https://www.etsy.com/developers/documentation/reference/listinginventory

    The endpoint expects multiple price_on_property field as form parameter. The library blocking this usage type. It blocks my project at the same time :). If there is no plausible reason to prevent this better to make pull request to change the behaviour.

    opened by oguzhantopcu 5
  • RSA private key cannot be defined

    RSA private key cannot be defined

    I need to define a precomputed private key for the oauth connection for Jira as described here http://blog.michael.kuron-germany.de/2013/04/two-legged-oauth-between-php-and-jira/

    I do not see how to do this. Can you give me an example on how to do this?

    opened by zimmski 5
  • Unable to send tweet

    Unable to send tweet

    First, thanks for the lovely implementation!

    Unfortunately, while I can use it to read information (e.g. mentions_timeline, etc), it does not actually allow me to send a tweet.

    I followed these steps:

    1. Created an app, with Read-write privileges
    2. Fixed up the tweet example in examples/twitter/twitter.go to compile, using PostForm
    3. Passed it my consumerkey and consumersecret, and successfully authorized it and fed it the verification code.
    4. It failed to send the tweet this error:
    2012/10/23 21:59:23 HTTP response is not 200/OK as expected. Actual response: 
        Response Status: '401 Unauthorized'
        Response Code: 401
        Response Body: {"request":"\/1\/statuses\/update.json","error":"Could not authenticate with OAuth."}
        Requst Headers: [key: Authorization, val: OAuth oauth_consumer_key="XXX",oauth_nonce="4875187832361465491",oauth_signature="WfYXo%2Bug1ZlYeYeNrwNRGoIlAZk%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1351043963",oauth_token="203366885-AfOIR2WNi2hPS3ePMFGoKBCVSGZGmHOpTuC4Vino",oauth_version="1.0"]
    

    I suspect that it doesn't match what Twitter is expecting at all, and the only reason that some API calls work is that they return public information and they are not validating the signature on those.

    opened by robfig 5
  • Read http Request bodies in a go1.8+ compliant manner

    Read http Request bodies in a go1.8+ compliant manner

    This updates the way that http.Request Bodies are read in oauth.go to comply with Client & Transport changes to the net/http library in Go 1.8+.

    https://golang.org/doc/go1.8#net_http

    Specifically of interest here is the statement:

    The Transport no longer reads a byte of a non-nil Request.Body when the Request.ContentLength is zero to determine whether the ContentLength is actually zero or just undefined. To explicitly signal that a body has zero length, either set it to nil, or set it to the new value NoBody. The new NoBody value is intended for use by Request constructor functions; it is used by NewRequest.

    When reading the request body to calculate the content hash or to parse form-encoded query args, the NoBody value is being overwritten with an empty ReadCloser, even though the Content Length is 0. The impact of this is that as far as the net/http library is concerned, a Request which is passed to provider.IsAuthorized with a Content Length of 0 (Request.ContentLength ==0 && Request.Body == NoBody) is modified during the parsing/hash calc process such that it's effective Content Length is now undefined (Request.ContentLength ==0 && Request.Body != NoBody).

    As a result, passing a Reqeust to IsAuthorized unexpected changes the behavior of that request. e.g. the http Client will happily handle redirects with a 307 or 308 Status for requests with a body length of 0, but but it will not handle redirects with an undefined body length.

    Version Compatibility Issues These changes will only compile with go 1.8+. Let me know if you'd prefer I reopen this PR against a different upstream branch to maintain some minimum-go-version compatibility on master.

    opened by mffahey 4
  • Allows providers to include query string params in the base string for signing

    Allows providers to include query string params in the base string for signing

    Hey MrJones!

    So this PR is a little different. The issue we were having is that one of our devices (Roku) does not follow the oAuth specification as strictly as it should. The device is sending a POST request with query-string-parameters in the URL. Normally these values should not be included in the base string that get signed, however our company decided to tolerate this as this situation may exist in other devices.

    I would like to continue to use your library instead of forking and adding our own logic so I submit this PR in case you find that it would be useful in your library as an option that is off by default.

    opened by ericksonjoseph 4
  • Protect trailing = in signature

    Protect trailing = in signature

    Some signatures can end in an equal sign (ex: QE5GoUkrrI1SC/XmORhLGEeGe/c= )

    This fix stops the param splitter from over-splitting, instead splitting only on the first equal sign and leaving subsequent equal signs as part of the value in the KV pair.

    opened by themartorana 3
  • Return http execute error for authentication

    Return http execute error for authentication

    I'm using oauth to access a legacy service, which returns XML body rather than JSON if it runs into "invalid consumer key" and a few other cases. This is due to some problem on the service implementation but I'm not able to change their code.

    I want to extract the body and parse the message by myself, so I changed the getBody method from returning an errorString to simply the HTTPExecuteError so I can access every detail of the error.

    Thanks!

    opened by mogita 2
  • Not able to make OAUTH Post call

    Not able to make OAUTH Post call

    I am trying to make a POST call to remote server which has OAUTH like this

    globals.Consumer.PostJson(URL, postBody, globals.AccessToken) This works absolutely fine if I make GET call to the same remote server.

    I always get "Internal Server Error" Any suggestions.

    opened by tanujChilwal 2
  • Allows consumers to configure whether or not to check for the timestamp

    Allows consumers to configure whether or not to check for the timestamp

    Some providers allow a loose implementation of oauth1. The use-case we are experiencing is that our mobile team sends oauth requests with a 13-digit timestamp.

    opened by ericksonjoseph 2
  • Renew access token

    Renew access token

    Hi. Is there a way to renew an existing access token. The refresh token method doesn't handle scenarios where there is a separate url to renew access token

    opened by maheshnayer 1
  • app engine support

    app engine support

    App Engine requires use of context-specific HTTP clients. Outbound HTTP requests simply don't work unless there's a way to provide the current request context to the outgoing request.

    Because a *Consumer might outlast multiple requests, we need a way to thread the request context through and then optionally create an *http.Client based on it. Unfortunately, this requires adding a bunch of new arguments.

    My preference would be to require contexts for all callsites, but I realize that breaks backwards compatibility, so I've added new methods.

    opened by jtolio 1
  • Space not properly escaped

    Space not properly escaped

    I was getting signature failures when a query parameter had a properly escaped space. I replaced the existing escape method with url.QueryEscape and fixed. Patch below.

    diff --git a/oauth.go b/oauth.go
    index d8e0ea2..07cccac 100644
    --- a/oauth.go
    +++ b/oauth.go
    @@ -957,23 +957,7 @@ func (s *RSASigner) SignatureMethod() string {
     }
    
     func escape(s string) string {
    -       t := make([]byte, 0, 3*len(s))
    -       for i := 0; i < len(s); i++ {
    -               c := s[i]
    -               if isEscapable(c) {
    -                       t = append(t, '%')
    -                       t = append(t, "0123456789ABCDEF"[c>>4])
    -                       t = append(t, "0123456789ABCDEF"[c&15])
    -               } else {
    -                       t = append(t, s[i])
    -               }
    -       }
    -       return string(t)
    -}
    -
    -func isEscapable(b byte) bool {
    -       return !('A' <= b && b <= 'Z' || 'a' <= b && b <= 'z' || '0' <= b && b <= '9' || b == '-' || b == '.' || b == '_' || b == '~')
    -
    +       return url.QueryEscape(s)
     }
    
    opened by pchristopher1275 1
  • broken request if parameter contains

    broken request if parameter contains ";"

    hey @mrjones ,

    first of all, thanks for the nice library! i'm trying to re-use it in upwork/golang-upwork project, and i've found an interesting issue:

    params := make(map[string]string)
    params["q"] = "golang"
    params["paging"] = "1;10"
    
    line 675: t := userRequest.URL.Query()
    line 676: log.Fatal(userRequest)
    2015/08/10 07:59:26 &{GET https://www.upwork.com/api/profiles/v2/search/jobs.json?paging=1;10&q=golang HTTP/1.1 1 1 map[] <nil> 0 [] false www.upwork.com map[] map[] <nil> map[]   <nil>}
    
    seems to be OK, but:
    line 677: log.Fatal(t)
    2015/08/10 08:02:40 map[10:[] q:[golang] paging:[1]]
    HOW?!
    
    let's change params[q] to params["q"] = "golang;test"
    userRequest looks correct:
    2015/08/10 08:11:25 &{GET https://www.upwork.com/api/profiles/v2/search/jobs.json?q=golang;test&paging=1;10 HTTP/1.1 1 1 map[] <nil> 0 [] false www.upwork.com map[] map[] <nil> map[]   <nil>}
    but suddenly userRequest.URL.Query() returns:
    2015/08/10 08:12:51 map[paging:[1] 10:[] q:[golang] test:[]]
    

    jfyi, URL.Query() recognizes ";" and "&" as delimeters (http://stackoverflow.com/questions/3481664/semicolon-as-url-query-separator)

    quick fix can look like:

    diff --git a/oauth.go b/oauth.go
    index 3d195ce..d1b9b61 100644
    --- a/oauth.go
    +++ b/oauth.go
    @@ -669,6 +669,7 @@ func (rt *RoundTripper) RoundTrip(userRequest *http.Request) (*http.Response, er
            if userRequest.Header.Get("Content-Type") !=
                    "application/x-www-form-urlencoded" {
                    // Most of the time we get parameters from the query string:
    +               userRequest.URL.RawQuery = strings.Replace(userRequest.URL.RawQuery, ";", "%3B", -1)
                    for k, vs := range(userRequest.URL.Query()) {
                            if len(vs) != 1 {
                                    return nil, fmt.Errorf("Must have exactly one value per param")
    

    in that case library works as expected

    or the library could encode ";" before creating a request (and might decode it before signing a request to have a valid signature created), or smth similar

    opened by mnovozhylov 4
  • Add more structure to errors

    Add more structure to errors

    Carrying over @deet's comment from https://github.com/mrjones/oauth/pull/9 to a new bug:

    I've run into some other issues with using this function and those that return its result, and I'm not sure how they should be addressed. (Let me know if you want this as a separate issue.) Specifically, clients can't determine whether the call failed due to network error or because of something application-level (like non-2XX response). So far it seems necessary to do a substring match for "HTTP response is not 200/OK as expected" to determine that the call failed due to a server response. Any suggestions?

    Although I'm not entirely sure the best way to handle this canonically in Go, here's what I'm thinking:

    http://blog.golang.org/error-handling-and-go has a section called "The error type". That section stars by discussing creating errors with errors.New and fmt.Errorf, which is basically what this library is doing now.

    Starting with the "In many cases fmt.Errorf is good enough, but..." section, it goes on to describe defining an error struct, and then allowing callers to examine the details of that error using type assertion.

    So here are two ideas along those lines:

    1. Define a single new error type "OauthError" that extends the error type, and we can insert any additional information in there. I'm not 100% sure what would go in the struct, but you could imagine something like an httpStatusCode field, that was empty if no HTTP request was made.
    2. Define multiple new error types OauthHttpError, OauthNetworkError, GenericOauthError, whatever. Then the user can do type assertion and figure out which kind of error they got back.

    My first reaction is that the first option involves less type assertion, so seems a little cleaner, but both seem like they'd be totally fine.

    If you're want to, feel free to send a patch. Otherwise I'll try to write some code for this maybe in the next week or two.

    opened by mrjones 3
  • Consider merging with Gomniauth

    Consider merging with Gomniauth

    We are hosting and investing in Gomniauth which can support OAuth1 (but doesn't yet) - and would love your contributions: https://github.com/stretchr/gomniauth

    opened by matryer 0
OAuth 1.0a implementation in Go

Package oauth1a Summary An implementation of OAuth 1.0a in Go1. API reference Installing Run: go get github.com/kurrik/oauth1a Include in your source

Arne Roomann-Kurrik 23 Sep 17, 2021
Example of a simple application which is powered by a third-party oAuth 2.0 server for it's authentication / authorization. Written in Golang.

go mod init github.com/bartmika/osin-thirdparty-example go get github.com/spf13/cobra go get github.com/openshift/osin go get github.com/openshift/osi

Bartlomiej Mika 0 Jan 4, 2022
OauthMicroservice-cassandraCluster - Implement microservice of oauth using golang and cassandra to store user tokens

implement microservice of oauth using golang and cassandra to store user tokens

Mehdi 1 Jan 24, 2022
A Go library for doing header-based OAuth over HTTP or HTTPS.

Installation goinstall github.com/alloy-d/goauth Usage import ( "github.com/alloy-d/goauth" "os" ) func someFuncThatDoesStuffWithOAuth() (er

Adam Lloyd 24 Sep 2, 2020
GOAuth An Oauth consumer Written in Go V 0.0.5

GOAuth ====== This is the source code repository for the GOAuth an OAuth consumer written on the Go programming language. Copyright 2010 The GOAuth

null 50 Feb 11, 2021
A library for performing OAuth Device flow and Web application flow in Go client apps.

oauth A library for Go client applications that need to perform OAuth authorization against a server, typically GitHub.com. Traditionally,

GitHub CLI 333 Jul 14, 2022
an SSO and OAuth / OIDC login solution for Nginx using the auth_request module

Vouch Proxy An SSO solution for Nginx using the auth_request module. Vouch Proxy can protect all of your websites at once. Vouch Proxy supports many O

Vouch 2k Aug 8, 2022
Casdoor is a UI-first centralized authentication / Single-Sign-On (SSO) platform based on OAuth 2.0 / OIDC.

A UI-first centralized authentication / Single-Sign-On (SSO) platform based on OAuth 2.0 / OIDC

Casbin 3.8k Aug 4, 2022
OAuth 2.0 middleware service for chi (ported from gin by community member)

oauth middleware OAuth 2.0 Authorization Server & Authorization Middleware for go-chi This library was ported to go-chi from https://github.com/maxzer

go-chi 14 Jul 7, 2022
Server bridging Google's OAuth and service using Radius for authentication

Fringe Fringe is an easy workaround for Google Workplace users who need a Radius server to perform authentication on behalf of other services (e.g. 80

Pierre-Luc Simard 5 Mar 7, 2022
Demonstration of sharing secret data between an OAuth/OIDC client and an Identity Providers web client.

OAuth / OIDC Cubbyhole Share secret data between client applications. This is mostly a demonstration of some of the work I've been evaluating at Storj

mya 3 Mar 21, 2022
A library for Go client applications that need to perform OAuth authorization against a server

oauth-0.8.0.zip oauth A library for Go client applications that need to perform OAuth authorization against a server, typically GitHub.com. Traditiona

tigressma 1 Oct 13, 2021
Authentication Plugin for implementing Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0, SAML Authentication

Authentication Plugin for implementing Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0, SAML Authentication

Paul Greenberg 490 Aug 8, 2022
Goauth: Pre-made OAuth/OpenIDConnect and general authorization hooks for webapp login

goauth Pre-made OAuth/OpenIDConnect and general authorization hooks for webapp login. Currently supports Google, Facebook and Microsoft "out of the bo

Steven Frew 0 Jan 28, 2022
goRBAC provides a lightweight role-based access control (RBAC) implementation in Golang.

goRBAC goRBAC provides a lightweight role-based access control implementation in Golang. For the purposes of this package: * an identity has one or mo

Xing 1.3k Aug 1, 2022
This is an implementation of JWT in golang!

jwt This is a minimal implementation of JWT designed with simplicity in mind. What is JWT? Jwt is a signed JSON object used for claims based authentic

John Rowley 99 May 9, 2022
Golang implementation of JSON Web Tokens (JWT)

jwt-go A go (or 'golang' for search engine friendliness) implementation of JSON Web Tokens NEW VERSION COMING: There have been a lot of improvements s

Dave Grijalva 10.4k Aug 3, 2022
Platform-Agnostic Security Tokens implementation in GO (Golang)

Golang implementation of PASETO: Platform-Agnostic Security Tokens This is a 100% compatible pure Go (Golang) implementation of PASETO tokens. PASETO

Oleg Lobanov 617 Jul 30, 2022
Golang implementation of JWT and Refresh Token

Fiber and JWT with Refresh Token Repo ini adalah demostrasi JWT support refresh token tanpa menggunakan storage Branch Main: unlimited refresh token R

Muhamad Surya Iksanudin 15 Aug 3, 2022