I've been battling with OAuth and Twitter for 2 weeks now trying to implement it. After many rewrites of my code I've finally got a library which performs the request as it should be based on the 1.0 spec. I've verified it by using this verifier on Google Code, and this verifier from Hueniverse.
My version, the Google version and the Hueniverse version all produce the exact same signature, so I've concluded that I am no longer the cause (but I could be putting a foot in my mouth by stating this...).
I test my implementation by first creating a test request using Twitter's API Console, in this case a status update. I copy the params that change, the oauth_nonce and oauth_timestamp, into all three signers stated above. All other params are always the same, tokens/secrets/etc.
Twitter's console produces one signature, but the other three above all produce a different signature (from Twitter's, identical to each other).
So, my question is, why am I getting this:
<?xml version="1.0" encoding="UTF-8"?>
<hash>
<request>/1/statuses/update.xml</request>
<error>Could not authenticate with OAuth.</error>
</hash>
...when I should be implementing the spec to the "T"?
Is there something specific that Twitter needs/wants as part of the request? I've counted the nonce generated by Twitter as 42 chars long, is that correct? Should it be 42 chars long?
I would appreciate help from anyone with more insight into the API than I obviously have...
Thanks in advance!
UPDATE: Someone asked about how I send the authentication params, but has since deleted their post, idk why. Anyway, the authorization params are sent via the Authorization header.
UPDATE/SOLUTION: Is moved down to the bottom where it belongs as an answer.
The only problem I had when implementing the OAuth specification with Twitter as the main target was, that Twitter has restricted the nonce to only accept ASCII characters (while the specification actually allows any bytes). Therefor I changed my implementation to generate a random int (with 60 bits, so longer than 42 chars) instead.
Other than that, Twitter's implementation seems to be completely correct; at least I didn't have any issues.
I suggest you to use some of the many OAuth sandboxes around (for example this or this) to really check if everything goes right and for example if you include everything necessary into the signature etc..
A little late, but per #poke's suggestion, I'm adding my answer down here:
So, I figured it out, and it's actually quite stupid. A while back, probably rewrite 3, I was getting back bad non-XML response from Twitter. I then saw that in the Twitter API Console they escape the header params: param=\"value\". I added the backslash to mine and instantly I was getting back an XML response. So it stuck.
Anyway, just to rule everything out from rewrite 7 (or 8), I decided to remove the backslash from the header params string and it resolved everything.
So, the lesson learned from all of this is that not everything that the Twitter API Console displays should be mimicked. I actually would further suggest that Twitter updates the console to display what a header string should look like when sent and not what their system generates internally, which parses the backslash chars.
Related
I have tried the C# sample at https://learn.microsoft.com/en-us/azure/azure-monitor/platform/data-collector-api butI always get an error response back. Has anyone been able to get this sample to work? I have double and triply checked the workstation id and the secret key but still cannot call the API sucessfully.
Yes, as Doris Lv mentioned, displaying the error would certainly help to understand the issue better.
In additional to it what I could observe in general is, the C# example provided for the Azure Monitor Data Collector API uses ASCII encoding while other parts of the page reference UTF8 so try to tweak your code with UTF8 and see if it resolves your error.
I am using C# WAMP client to connect to the Poloniex exchange to get the real time Market data.AS per the documentation provided by the exchange in order to create a real time order book we have to first get the snapshot of the order book through REST api provided by them and extract the sequence number from it and then connect to the WAMP server to get the streaming data and update the order book snapshot.
I have problem in updating the snapshot order book received through rest api since the sequence number which I received through the REST api is nearly 400k record ahead of the sequence number received through WAMP.
Is there any other way which I could get the real time Streaming data from the POloniex exchange or am I missing anything?
I have the same problem. Seems they have some bug. What I have noticed is that there are different sequences sent in normal update messages and in "heartbeat" messages (the ones without payload). The documentation states that a heartbeat message should repeat the last normal message sequence number. But it differs. However it corresponds to a number returned by REST API. So seems that "works" for heartbeat messages and wrong for normal ones. Looks pretty much as a bug.
Here is also some related question.
UPD: Also checked "newTrade" events with trade history returned by the REST API. Trade IDs in WAMP are significantly lower than actual ones in a snapshot. Seems the events published via push API are outdated by several hours and that is the explanation of all this behaviour. So the push API is unusable now.
And finally, seems that current way to go is using their pure WebSocket API which is used by web-interface. It is located at wss://api2.poloniex.com. The only problem is lack of documentation. One way is reverse engineering the traffic of the web-interface. Some poor pieces of information although can be found in code snippets like this or in discussion here.
The original websocket does not seem to be active. The one that is active is indeed: wss://api2.poloniex.com. I am coding my app in swift but maybe you will find this helpful. For orderbook entries I send the following message: "{"command":"subscribe","channel":"(coinPair)"}".
It is very important to use the quotes correctly (as above). The "(coinPair)" is string interpolation so you can include whatever coin pair you want to get the orderbook for. Of course you have to eliminate the (). These are for swift only.
If you want to get a live feed of the prices of all of the tickers you have to send the following message: "{\"command\":\"subscribe\",\"channel\":1002}". Again be careful to use the correct quotes.
Hope this helps.
I have few questions concerning PayPal and Classic API. I have spent the last few days reading and experimenting with 1. Single PayPal Payment using variables and HTML post form. 2. Idem but for recurring/subscription payments. Even though I almost succeed to do most of what I want to accomplish, I still have few questions and grey zone I'd like to debunk.
Here it is:
Is it possible to use classic API, HTML form, PayPal variables and post a request to PayPal/Sandbox AND ONLY use credit card information, without having to log in PayPal or have a PayPal account? I never succeed and PayPal always block after you hit the PAY button, returning security codes error message or wrong card/account number etc.
If yes, how and where can I find a real code sample or demo for HTML/MVC-C#?
After a make a payment, I receive an invalid response which nothing happens, then, I receive a second IPN response and this one is verified etc. DO I really need to reply to PayPal/Sandbox to tell them everything is OK? If yes, is there info somewhere or code sample/demo I can see? MY point here is because i receive MANY hits on my IPN and I want to make sure I get the right response, make sure i don't DOUBLE subscribe etc..
Is there A GOOD MVC or C# IPN code sample somewhere? One I could read and analyse/take to handle most possible scenarios/errors/response code and what to do with them? not to copy and paste but something reliable I could adapt to my code.
I have succeeded to get a response to my IPN with a PayPal account only and I had to somehow hack security protocol using this instruction --> ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;//SecurityProtocolType.Tls1.2; and I also had to use ngrok to provide a 'valid' return URL. My question here is, Do I Need to remove that instruction when I go PROD?
Thank you so much in advance,
Mart.
Yes, but this is one of the reasons the question got voted down. You need to sign up for Payments Pro to do credit cards (or you could also use the REST API) and then you would use those specific APIs to process credit cards. The thing is, depending on what version of Pro you end up with or if you decide to go with REST, the APIs are different, so it's hard for anybody to tell you what to use at this point.
Yes, you need to POST back to PayPal to verify that the data actually came from them. This way you can trash any data where wannabe hackers are posting garbage to your IPN listener or anything else like that going on.
As long as your IPN script completes with a successful 200 response back from your server then PayPal will only send a single IPN. If you're getting multiples you must have a failure going on, in which case you'll need to troubleshoot that accordingly.
Yes, PayPal provides lots of sample code. This is another reason your question may have been voted down. It seems you have not taken the time to look into this stuff yourself. Go to http://developer.paypal.com and upon reviewing the APIs you'll find they provide SDKs for different languages. Each of those comes with samples, and their GitHub repos also include samples.
With a quick Google search you'll find loads of tutorials and samples as well, of course.
Within the developer site you'll also find the Integration Wizard, which will let you choose C#, choose the payment integration you want, and it will build it all for you so you can see how it works.
Then, when working on those samples or trying actual code, if you have specific problems / questions, you'd come here and post that specific issue with a code sample that you've tried. Then people here will be happy to help.
TLS 1.2 is a standard requirement for pretty much all web services now because of security vulnerabilities in SSLv3. If you have "hack" anything (outside of configuration files, maybe) then you're probably doing something unnecessary. All it would require is to ensure the software stack on your server not only supports TLS 1.2 HTTP requests, but also uses it by default.
I am using MonoTouch to call a remote web service from an iOS app. I use HttpWebRequest and it works great for me for GET, PUT, and POST requests. However, when I try to make a DELETE request, I get some odd behavior: the entity body that I send gets truncated and the server receives an empty body (Content-Length: 0).
The identical code works perfectly when run on a Windows Phone with the WP7.1 implementation of System.Net.HttpWebRequest.
I know that there is some debate on whether RFC 2616 allows an entity body in a DELETE request (e.g. Phil Haack's question). This question isn't about that - it is about why the body does not make it to the server.
Now to the question :-) Is this issue in MonoTouch's implementation of HttpWebRequest (i.e. Mono enforces a Content-Length of 0 for the body of a DELETE request)? Or does Mono implement HWR on top of an Apple framework that is responsible for this behavior? The reason for the question, of course, is to better understand whether I can work around the issue and/or implore Miguel to allow DELETE bodies, or whether I need to change my wire format.
This looks like a bug in Mono, after a (very) quick look in the source code I found this, which seems to be the culprit.
You should file a bug with a test case so it can be fixed (even better: provide a patch as well, in which case it shouldn't take long to get it fixed).
I've been throwing a little bit of spare time at writing a BitTorrent client, mostly out of curiosity but partly out of a desire to improve my c# skills.
I've been using the theory wiki as my guide. I've built up a library of classes for handling BEncoding, which I'm quite confident in; basically because the sanity check is to regenerate the original .torrent file from my internal representation immediately after parsing, then hash and compare.
The next stage is to get tracker announces working. Here I hit a stumbling block, because trackers reject my requests without terribly useful error messages.
Take, for instance, the latest stack overflow database dump. My code generates the following announce URI:
http://208.106.250.207:8192/announce?info_hash=-%CA8%C1%C9rDb%ADL%ED%B4%2A%15i%80Z%B8%F%C&peer_id=01234567890123456789&port=6881&uploaded=0&downloaded=0&left=0&compact=0&no_peer_id=0&event=started
The tracker's response to my code:
d14:failure reason32:invalid info hash and/or peer ide
The tracker's response to that string dropped into Chrome's address bar:
d8:completei2e11:external ip13:168.7.249.11110:incompletei0e8:intervali600e5:peerslee
The peer_id is (valid) garbage, but changing it to something sensible (impersonating a widely used client) doesn't change anything.
Like I said, I'm pretty sure I'm pulling the info dictionary out properly and hashing (SHA1) like I should, and the peer id is well formed.
My guess is I'm doing some minor thing stupidly wrong, and would appreciate any help in spotting what it is exactly.
Its kind of hard to guess what code would be pertinent (and there's far to much to just post). However, I'll try and post anything asked for.
EDIT
I wasn't hex encoding the info_hash, which sort of helps.
This is the code that takes the generates URI and try's to fetch a response:
//uri is the above
WebRequest req = WebRequest.Create(uri);
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
MonoTorrent is a BitTorrent implementation that comes with Mono.
In the HTTPTracker class there is a CreateAnnounceString method.
Maybe you can compare your implementation with how that method is doing it?
(You probably need to hunt down where the AnnounceParameters instance is created.)
This isn't an answer to your problem, but it may help for testing.
There are open-source PHP-based torrent trackers out there. They are incredibly inefficient (I know, I wrote a caching mechanism for one back in the day), but you could set up your own local tracker and modify the PHP code to help debug your client as it communicates with the tracker. Having a local client-server setup would make troubleshooting a lot easier.
What exactly are you hashing? You should only hash the info section, not the whole torrent file... So basically, decode the file, reencode the info section, hash that.
ie. For the torrent posted, all you should be hashing is:
d6:lengthi241671490e4:name20:so-export-2009-07.7z12:piece lengthi262144e6:pieces18440:<lots of binary data>e
There is a error in the URL %-encoding of the info_hash. The leading zeros in the two last bytes of the info_hash has been removed.
It is: info_hash=-%CA8%C1%C9rDb%ADL%ED%B4%2A%15i%80Z%B8%F%C
Should be: info_hash=-%CA8%C1%C9rDb%ADL%ED%B4%2A%15i%80Z%B8%0F%0C
When the announce string is dropped into Chrome's address bar it's probably auto-corrected by the browser.