XAuth fail when password contains a "#"
I am experiencing a very weird error with my xauth implementation.
It fails when the password contains a "#". I snooped out the raw headers, and it looks almost exactly the same as another app that works, except for a different looking nonce (does it matter开发者_StackOverflow?)
The code i am using is here: http://pastie.org/2436098
--------MY LIBRARY :FAIL--------
POST /oauth/access_token HTTP/1.1
Host: api.twitter.com
User-Agent: onethingaday/1.0 CFNetwork/485.13.8 Darwin/10.7.0
Authorization: OAuth oauth_nonce="70943970", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1314400256", oauth_consumer_key="fmYDyQZ1IRz6sYuhOAQbJQ", oauth_signature="1VYDQYL5WvkbovQggNUjuY9t%2Fvc%3D", oauth_version="1.0"
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 78
Connection: keep-alive
Proxy-Connection: keep-alive
x_auth_mode=client_auth&x_auth_username=kkklllkkk1&x_auth_password=kkkk%23kkkk
--------SNOOPING ANOTHER APP : SUCCESS--------
POST /oauth/access_token HTTP/1.1
Host: api.twitter.com
User-Agent: XAuthTwitterEngineDemo/1.0 CFNetwork/485.13.8 Darwin/10.7.0
Content-Length: 78
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth realm="", oauth_consumer_key="fmYDyQZ1IRz6sYuhOAQbJQ", oauth_signature_method="HMAC-SHA1", oauth_signature="mEyjwksg1NoaY2VMQBf70ZN3OhM%3D", oauth_timestamp="1314400386", oauth_nonce="4DF9C426-08F8-49FC-9E1B-576FDBDA8836", oauth_version="1.0"
Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive
Proxy-Connection: keep-alive
x_auth_mode=client_auth&x_auth_username=kkklllkkk1&x_auth_password=kkkk%23kkkk
Most likely you've bungled the signature base string. The way you're building your parameters is trying to shortcut and alter some of the steps, and it seems to be missing an encoding level. You're building a parameter list of elements like:
E(k) + E('=') + E(v)
then sorting them by the combined, encoded key-value pair string, then combining all those strings like
P_{i} + E('&') + P_{i + 1}
This misses an encoding level for the pairs, because what you're supposed to end up with for the part of the signature base string corresponding to the parameters is actually (assuming two key-value pairs for simplicity):
E(E(k) + '=' + E(v) + '&' + E(k2) + '=' + E(v2))
=
E(E(k)) + E('=') + E(E(v)) + E('&') + E(E(k2)) + E('=') + E(E(v2))
This means that the %
signs in the percent-escaped characters of the keys and values are themselves escaped, so #
turns into first %23
and thence into %2523
, because E('%') = '%25'
.
If you follow the standard step-by-step, you should do fine. If you depart from the standard without a proof of equivalence, you're likely to go astray.
精彩评论