mrjones / oauth Goto Github PK
View Code? Open in Web Editor NEWOAuth 1.0 implementation in go (golang).
Home Page: http://www.mrjon.es
License: MIT License
OAuth 1.0 implementation in go (golang).
Home Page: http://www.mrjon.es
License: MIT License
Looking at Twitter example I tried to implement it for my project. Below you can see 2 functions:
But I am getting:
2013/11/19 05:19:39 httpExecute: HTTP response is not 200/OK as expected. Actual response:
Response Status: '401 Unauthorized'
Response Code: 401
Response Body: Invalid request token
Requst Headers: [key: Authorization, val: OAuth oauth_consumer_key="eGhxxEwyi1AOgQhtQNi1g",oauth_nonce="6812501655763588603",oauth_signature="5%2Ffqo84h2tfujYk3q6x13dpdaY8%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1384831178",oauth_token="2SzuHTzXp93rj4TJJXy0sHYs2Wg7l9pTpNE3oLs8",oauth_verifier="",oauth_version="1.0"][key: Content-Length, val: 0]
exit status 1
My code:
func AskTwitterVerificationCode(w http.ResponseWriter, r *http.Request) {
c := oauth.NewConsumer(
config.TwitterConsumerKey,
config.TwitterConsumerSecret,
oauth.ServiceProvider{
RequestTokenUrl: "http://api.twitter.com/oauth/request_token",
AuthorizeTokenUrl: "https://api.twitter.com/oauth/authorize",
AccessTokenUrl: "https://api.twitter.com/oauth/access_token",
},
)
if config.Debug {
c.Debug(true)
}
var requestUrl, tokenUrl string
if config.Debug {
tokenUrl = "http://myapp.com:"+strconv.Itoa(config.Port)+"/auth/twitter/callback"
} else {
tokenUrl = "http://myapp.com/auth/twitter/callback"
}
var err error
_, requestUrl, err = c.GetRequestTokenAndUrl(tokenUrl)
if err != nil {
log.Fatal(err)
}
http.Redirect(w, r, requestUrl, http.StatusMovedPermanently)
}
func GetTwitterToken(w http.ResponseWriter, r *http.Request) {
c := oauth.NewConsumer(
config.TwitterConsumerKey,
config.TwitterConsumerSecret,
oauth.ServiceProvider{
RequestTokenUrl: "http://api.twitter.com/oauth/request_token",
AuthorizeTokenUrl: "https://api.twitter.com/oauth/authorize",
AccessTokenUrl: "https://api.twitter.com/oauth/access_token",
},
)
if config.Debug {
c.Debug(true)
}
var tokenUrl string
var requestToken *oauth.RequestToken
if config.Debug {
tokenUrl = "http://myapp.com:"+strconv.Itoa(config.Port)+"/auth/twitter/callback"
} else {
tokenUrl = "http://myapp.com/auth/twitter/callback"
}
var err error
requestToken, _, err = c.GetRequestTokenAndUrl(tokenUrl)
if err != nil {
log.Fatal(err)
}
values := r.URL.Query()
verificationCode := values.Get("oauth_verifier")
log.Println(verificationCode)
accessToken, err := c.AuthorizeToken(requestToken, verificationCode)
if err != nil {
log.Fatal(err)
}
fmt.Fprintf(w, accessToken.Token, " and ", accessToken.Secret)
}
See subject.
If you're given 4 tokens straight away
What order of functions do you use? Will oauth.NewConsumer()
work without the request URLs?
Carrying over @deet's comment from #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:
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.
I've looked through the API a bit and it seems like it is designed around providing the capability to send a signed request but not necessarily verify an incoming OAuth request.
I was wondering if there is anyway to verify a incoming OAuth request using this library?
In the Twitter example, it shows how to upgrade a requestToken to an accessToken here.
When I test that method, I receive the following error: Missing oauth_token in response. Full response body: 'ok'
.
I checked that my requestToken and verificationCode in the method are valid. I also pointed a test request at requestb.in to see what the request was sending. Here's the full request that's sent:
Note that the raw body is "None". I believe the issue is that in Step 3 of Twitter's oauth instructions, it wants the oauth_verifier as part of the request body like this: oauth_verifier=uw7NjWHT6OJ1MpJOXsHfNxoAhPKpgI8BlYDhxEjIBY
.
I may dig in and fix this, but in the meantime or if I don't, I wanted to let you folks know. Thank you!
I had some problems with duplicate nonces when using this library on Google App Engine. I traced it back to time.Now().Unix() being used for the random seed. I think it happened because App Engine started multiple instances in the same second and they all ended up getting the same random seed.
using time.Now().UnixNano() fixed the problem for me, and might be a better choice for the library.
Oh and thanks for this library, it is A+++ 100% awesome-sauce.
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
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)
}
Line 835 in 78d6446
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.
I am getting this error with Twitter, please help
getBody: httpExecute: HTTP response is not 200/OK as expected. Actual response: Response Status: '401 Authorization Required' Response Code: 401 Response Body: {"errors":[{"code":32,"message":"Could not authenticate you."}]} Request Headers: [key: Authorization, val: OAuth oauth_callback="http%3A%2F%2F162.243.216.116%3A3000%2Fauth%2Ftwitter%2Fcallback",oauth_consumer_key="bu7KHEjK7UTfNReTcG4gK",oauth_nonce="1527203789697",oauth_signature="Y0zXln26LPHveIjbs%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1465900095",oauth_version="1.0"]
Here is the code I am using: https://gist.github.com/motyar/dd1a441ed7214439afcb388b6c26b567
There are cases when clients need the HTTP body content even on non-200 responses.
I'm not sure why the library currently returns nil instead of just passing the response along with an error, although I might be missing something.
Would you consider a patch like this?
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
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.
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
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:
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.htmlThe 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
This library needs a proxy support to serve requests on proxies. That current model of http.Transport is not compatible with it.
Regards.
The current MIT-LICENSE.txt
can not be detected by heuristics of tools like go-licenses.
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?
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:
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.
It fails in jira.go example trying to read the privateKey. This is the error:
2015/09/30 11:23:51 asn1: structure error: tags don't match (2 vs {class:0 tag:16 length:13 isCompound:true}) {optional:false explicit:false application:false defaultValue: tag: stringType:0 set:false omitEmpty:false} @5
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.