I am trying to use Twitter OAuth and my POST requests are failing with a 401 (Invalid OAuth Request) error.
For example, if I want to post a new status update, I am sending a HTTP POST request to https://twitter.com/statuses/update.json with the following parameters -
status=Testing&oauth_version=1.0&oauth_token=xxx&
oauth_nonce=xxx&oauth_timestamp=xxx&oauth_signature=xxx&
oauth_consumer_key=xxx&in_reply_to=xxx&oauth_signature_method=HMAC-SHA1`
My GET requests are all working fine. I can see on the mailing lists that a lot of people have had identical problems but I could not find a solution anywhere.
I am using the oauth.py Python library.
I just finished implementing twitter OAuth API from scratch using Java. Get and post requests work OK. You can use this page http://www.hueniverse.com/hueniverse/2008/10/beginners-gui-1.html to check signature and HTTP headers. Just enter your keys and tokens and check output. It seems twitter works exactly as described on this post. Be careful with spaces and UTF-8 symbols, for example Java encodes space as "+" but OAuth requires %20
Make sure your app access type is read & write.
On your app settings page (ex. http://twitter.com/apps/edit/12345) there's a radio button field like this:
Default Access type: Read & Write / Read-only
If you check 'Read-only' then status update API will return 401.
I second the answer by Jrgns. I has exactly the same issue. When reading the example Twitter provides, it's actually clear. However their pseudo code is misleading. In Python this worked for me :
def encodekeyval(key, val):
key = urllib.quote(key, '')
val = urllib.quote(val, '')
return urllib.quote(key + '=' + val, '')
def signature_base_string(urlstr, oauthdata):
sigstr = 'POST&' + urllib.quote(urlstr,'') + '&'
# retrieve "post" data as dictionary of name value pairs
pdata = oauthdata.getpdata()
# need to sort parameters
pstr = '%26'.join([encodekeyval(key, pdata[key]) for key in sorted(pdata.keys())])
return sigstr + pstr
I had the same issues, until I realised that the parameters need to be encoded twice for the base string. My GET requests all worked fine, but my POSTs, particularly status updates, failed. On a hunch I tried a POST without spaces in the status parameter, and it worked.
In PHP:
function encode($input) {
return str_replace('+', ' ', str_replace('%7E', '~', rawurlencode($input)));
}
$query = array();
foreach($parameters as $name => $value) {
$query[] = encode($name) . '=' .encode($value);
}
$base = encode(strtoupper($method)) . '&' .encode($norm_url) . '&' .
encode(implode('&', $query));
Notice the encode function around the names and values of the parameters, and then around the whole query string. A Space should end up as %2520, not just %20.
I found the solution and it works for me, You must add the following paramters in the request header and it should look like following (c# code), donot use & sign, instead separate parameters by comma(,) sign. and you must add the word "OAuth" in the beginging.
httpWebRequest.Headers[System.Net.HttpRequestHeader.Authorization] = "OAuth oauth_consumer_key=\"hAnZFaPKxXnJqdfLhDikdw\", oauth_nonce=\"4729687\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1284821989\", oauth_token=\"17596307-KH9iUzqTxaoa5576VjILkERgUxcqExRyXkfb8AsXy\", oauth_version=\"1.0\", oauth_signature=\"p8f5WTObefG1N9%2b8AlBji1pg18A%3d\"";
and other parameters like 'status' should be written in the body of the request.
Most likely, the signature is invalid. You must follow the OAuth spec on how to generate the signature( normalized parameters, URLencoding, and cosumerSecret&oauthScret. More on this later ......
Related
I'm working with an API set that requires a Session Key to be pulled down and used in the Authorization Header for subsequent calls to the service. The value to be added to the Header is X-CardConnect-SessionKey See below for example. The first 20-digits, everything in front of the semi-colon, needs to be included in future calls to the service once obtained.
This is what I'm getting -->
X-CardConnect-SessionKey →9ffcd7dc737f4b9fbdccb299b9c55f4b;expires=2017-12-28T20:54:19.652Z
This is what I need:
X-CardConnect-SessionKey →9ffcd7dc737f4b9fbdccb299b9c55f4b
In Postman I am using the following to parse the Session Key value into my environment:
var data = responseHeaders
postman.setEnvironmentVariable ("X-CardConnect-SessionKey", data["X-
CardConnect-SessionKey"])
Naturally, the full string is inserted into the Environment when I only need the first 20 digits. Is there a way to limit the character limit so that only the first 20 digits are returned?
Thanks!
You can split the value using native JS or look at using one of the Lodash _.split() functions.
var data = "9ffcd7dc737f4b9fbdccb299b9c55f4b;expires=2017-12-
28T20:54:19.652Z"
postman.setEnvironmentVariable("test", data.split(';',1));
Or for what you need something along these lines:
var data = responseHeaders
postman.setEnvironmentVariable("X-CardConnect-SessionKey", data.X-
CardConnect-SessionKey.split(';',1))
Was able to resolve with the following:
const data = responseHeaders;
postman.setEnvironmentVariable ("X-CardConnect-SessionKey", data["X-CardConnect-SessionKey"]);
const sessionheader = data["X-CardConnect-SessionKey"];
postman.setEnvironmentVariable ("X-CardConnect-SessionKey", sessionheader.substring(0, 32));
I sent one request as URL with data to servlet, But by default servlet is modifying the data and sending as request. Can you please suggest how to maintain the request URL with data which i passed to servlet should remain same ?
Example:- when i am passing the data to servlet
http://localhost/helloservlet/servlet/ppd.abcd.build.coupons.CouponValueFormatterServlet?dsn=frd_abc_abcde&lang=ENG&val=PRCTXT|12345 &ABCDEFG
when it using the above url in servelt as request , like string abc = request.getParameter("val"), the val attribute is trimmed automatically and assigned as " val=PRCTXT|12345" but it supposed to be like " val = PRCTXT|12345 &ABCDEFG ". Please help me on this.
The servlet interprets each & in the URL as the start of a new parameter. So when it sees &ABCDEFG, it thinks you are sending a new parameter called ABCDEFG with no value (though this is technically a "keyless value" according to the specifications).
Two things to fix this, first is when you want to actually send an &, use %26 instead. This will be skipped by the code that divides up the parameters, but converted to a real & in the parameter's value.
Second is to replace spaces with +. Spaces in URLs work sometimes but can be problematic.
So your actual request URL should look like this:
http://localhost/helloservlet/servlet/ppd.abcd.build.coupons.CouponValueFormatterServlet?dsn=frd_abc_abcde&lang=ENG&val=PRCTXT|12345+%26ABCDEFG
If you're building these parameters in javascript, you can use encodeURIComponent() to fix all problem characters for you. So you could do something like this:
var userInput = *get some input here*
var addr = 'http://www.example.com?param1=' + encodeURIComponent(userInput);
I am using a jQuery ajax command, which has the following data:
$.ajax({
type:"POST",
...
data:"e=f_s&es="+JSON.stringify(email)+"&fr="+str
...
})
Where (email) can contain special character, for example it can be a string:
!#$%'&+-/=?^`*{|}~ch!#$%'/=?*^`{|}#mail.com
The reason why I allow such characters, is based on the following question.
The problem is, at some point on the server (Java EE application), it is messing up. The special characters are not showing the boundaries of different request parameters. For example it is considering : '/ as a parameter.
I think I need to escape characters? (if yes how?)
What should I do to be able to send such a string from javascript to java ?
Use encodeURIComponent:
encodeURIComponent("!#$%'&+-/=?^`*{|}~ch!#$%'/=?*^`{|}#mail.com")
returning:
"!%23%24%25'%26%2B-%2F%3D%3F%5E%60*%7B%7C%7D~ch!%23%24%25'%2F%3D%3F*%5E%60%7B%7C%7D%40mail.com"
(Camel 2.9.2)
Very simple use case, but I can't seem to find the answer. My code boils down to this:
String user = "user";
String password = "foo&bar";
String uri = "smtp://hostname:25?username=" + user +
"&password=" + password +
"&to=somthing#something.com"; // etc. You get the idea
from("seda:queue:myqueue").to(uri);
Camel throws a ResolveEndpointFailedException with "Unknown parameters=[{bar=null}]."
If I try "foo%26bar," I get the same result.
If I try "foo&bar" camel responds with "Unknown parameters=[{amp;bar=null}]."
I tried using URISupport to create the URI. It escapes the & to %26, and then I get "Unknown parameters=[{bar=null}]" again.
Any ideas?
As from Camel 2.11 you could use raw syntax
For instance:
.to("ftp:joe#myftpserver.com?password=RAW(se+re?t&23)&binary=true"
In the above example, we have declare the password value as raw, and
the actual password would be as typed, eg se+re?t&23
https://cwiki.apache.org/confluence/display/CAMEL/How+do+I+configure+endpoints
You can specify the password as part of the authority of the uri, eg in the front.
Also the & should be escaped to %26, but there was a bug in Camel that didnt parse the escaped value to well. Try 2.10 when its out.
The RAW() syntax works, yet it is Camel-proprietary syntax. In our usecase it burdened following processing of URI.
We used alternative solution: component configured as using raw URIs (Component.useRawUri() == true). Component parameters are then simply once encoded (foo%26bar) and pass through Camel without change. I consider this solution better as percent-sign encoding is standard way of expressing sensitive characters.
For a very simple ajax name lookup, I'm sending an id from the client webpage to the server (Tomcat 5.5, Java 5), looking it up in a database and returning a string, which is assigned to a javascript variable back in the client (and then displayed).
The javascript code that receives the value is pretty standard:
//client code - javascript
xmlHttp.onreadystatechange=function() {
if (xmlHttp.readyState==4) {
var result = xmlHttp.responseText;
alert(result);
...
}
...
}
To return the string, I originally had this in the server:
//server code - java
myString = "...";
out.write(myString.getBytes("UTF-8"));
Which worked perfectly, if unsafe. Later, I replaced it with:
import org.apache.commons.lang.StringEscapeUtils;
...
myString = "...";
out.write(StringEscapeUtils.escapeJavaScript(myString).getBytes("UTF-8"));
But while safer, the resulting string can't be properly displayed if it contains special chars like "ñ".
For instance, using:
escapeJavaScript("años").getBytes("UTF-8");
sends:
an\u00F1os
to the client.
The question: is there a simple way to parse the resulting string in Javascript or is there an alternate escape function I can use in java that would prevent this issue?
The following works in every browser I've tried:
javascript:alert("a\u00F1os");
Perhaps your string is being escaped twice by mistake.
Actually, now that I read it over, I think I actually don't need to escape the string I'm sending back at all... That is, StringEscapeUtils.escapeJavaScript would be useful if the resulting value was printed in the page, like:
//javascript code with inline struts
var myJavasriptString = "<%=myJavaString%>";
Or am I missing something and there would still be a valid reason to do the escape in the original case? (when it is returned as a series of bytes back to an ajax onreadystatechange handler and assigned to a js variable)