Bitstamp API: Always receiving API0000 (Missing key, signature and nonce parameters.) - java

Studying this SO question ( Authenticated Java Jersey REST call to Bitstamp ), I see that OP had a similar issue. Unfortunately, I can't make the call work in my own implementation: I tried sending key, nonce and signature both via query-parameters as well as json formatted in the request's body. I logged headers and content, so in those two cases, these are the resulting logs:
// send in body
---> POST https://www.bitstamp.net/api/v2/balance/ HTTP/1.1
Accept: application/json;charset=UTF-8
Content-Type: application/json;charset=UTF-8
Content-Length: 140
{"key":"12345678901234567890123456789012","nonce":1234567890,"signature":"1234567890123456789012345678901234567890123456789012345678901234"}
---> END HTTP (140-byte body)
<--- HTTP/1.1 403 Authentication Failed (49ms)
{"status": "error", "reason": "Missing key, signature and nonce parameters.", "code": "API0000"}
<--- END HTTP (96-byte body)
// send as query-parameters
---> POST https://www.bitstamp.net/api/v2/balance/?key=12345678901234567890123456789012&signature=1234567890123456789012345678901234567890123456789012345678901234&nonce=1234567890 HTTP/1.1
Accept: application/json;charset=UTF-8
Content-Type: application/x-www-form-urlencoded
---> END HTTP (0-byte body)
<--- HTTP/1.1 403 Authentication Failed (45ms)
{"status": "error", "reason": "Missing key, signature and nonce parameters.", "code": "API0000"}
<--- END HTTP (96-byte body)
What am I doing wrong? What does bitstamp mean when it states
For a successful authentication you need to provide your API key, a signature and a nonce parameter.
(https://www.bitstamp.net/api/)
I use Feign as REST client. The two methods look like this:
#PostMapping(value = "api/v2/balance/", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
ResponseEntity<Map<String, Object>> getAccountBalanceQuery(#RequestParam("key") String key,
#RequestParam("signature") String signature,
#RequestParam("nonce") Integer nonce);
#PostMapping(value = "api/v2/balance/", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
ResponseEntity<Map<String, Object>> getAccountBalanceBody(#RequestBody BitstampAuth body);
Thanks!

Related

Rest web services(post) consumes json not working

So I am trying to create a simple webservice post that consumes json. But I am geting the error RESTEASY002010: Failed to execute: javax.ws.rs.NotSupportedException: RESTEASY003065: Cannot consume content type
My webservice:
#POST
#Produces(MediaType.APPLICATION_XML)
#Path("teste1")
#Consumes(MediaType.APPLICATION_JSON)
public Response teste1(String product) {
String result = "Product created : " + product;
System.out.println("resultado");
System.out.println(result);
return Response.ok() //200
.entity("<erro> none </erro>")
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.header("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With").build();
}
I also tried to do:
#Consumes("application/json")
But I am getting the same error. I can make it work if I do:
#Consumes("*/*")
But I can't understand why it doesn't work when I say it consumes json. To test the webservice I am using https://apitester.com/. With the folowing Post Data:
{
"key" : "value",
"array" : [
{ "key" : 1 },
{ "key" : 2, "dictionary": {
"a": "Apple",
"b": "Butterfly",
"c": "Cat",
"d": "Dog"
} },
{ "key" : 3 }
]
}
In general the
#Consumes("application/json")
specifies a content media type which webservice can handle.
But also you may need to explicitly specify an appropriate type in the Content-Type header for your request.
I am not familiar with the https://apitester.com but probably it does not send the Content-Type header by default
In such case your server can treat the request body as a plain text, for instance. That request would not be routed to your endpoint, because it is not designed for the plain text.
Setting the #Consumes(*/*) fixes that problem, because the wrong media type matches that pattern as well.
Could you please ensure that you sends the Content-Type: application/json with your POST request?

Convert String error response to Http Status code

In Java+Spring application I am using, from a third party called over RestTemplate , we get the error response in the JSON with 200 response code.
e.g
{
"errors": [{
"reason": "did not like the request",
"error": "BAD_REQUEST"
}]
}
How can I convert BAD_REQUEST to the 400 integer representations.
Apache HttpStatus inte does not seem to provide any interface to do so.
Maybe you can use org.springframework.http.HttpStatus:
String error = "BAD_REQUEST";
HttpStatus httpStatus = HttpStatus.valueOf(error);
int errorIntCode = httpStatus.value();
or more safe:
String error = "BAD_REQUEST";
HttpStatus httpStatus = Arrays.stream(HttpStatus.values())
.filter(status -> status.name().equals(error))
.findAny()
.orElse(HttpStatus.INTERNAL_SERVER_ERROR);
int errorIntCode = httpStatus.value();
More succinct and short
HttpStatus.OK.value();

Apache Jmeter : Post an object not working with ModelAttribute

I am working on stress testing our webapplication written in Spring-MVC.
I would like to send an object Person to the application. I have added a system out to get the email, but whenever I am sending the object, it is null. What am I doing wrong?
Server code :
#RequestMapping(value = "/person/add", method = RequestMethod.POST)
public String addPerson(#ModelAttribute("person") Person person, BindingResult bindingResult) {
try {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
System.out.println("String is "+json);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("Person add called"+person.getUsername());
person.setUsername(this.stripHTML(person.getUsername()));
int personId = this.personService.addPerson(person);
if (!(personId == 0)) {
Person person1 = this.personService.getPersonById(personId);
Collection<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
Authentication authentication = new UsernamePasswordAuthenticationToken(person1, null, authorities);
SecurityContextHolder.getContext().setAuthentication(authentication);
return "redirect:/canvaslisting";
} else {
return "redirect:/";
}
}
Object sent in body data :
{"person":{"id":0,"username":"testemail#gmail.com","firstName":"test","cleanCacheFlag":false,"googleDrive":false,"dropbox":false,"evernoteConsumed":false,"statusChangeTimeStamp":null,"useCalendar":false,"newsletterFlag":false,"tourSteps":null,"profession":null,"notiz":null,"telePhone":null,"lastVisitedBoards":null,"leftGroup":null,"optionalEmail":null,"facebookLink":null,"xingLink":null,"linkedinLink":null,"lastOnlineTimestamp":null,"userRole":null,"homePage":null,"excelImportQuota":0,"toEmail":null,"code":null,"authorities":null,"role":null,"newpassword":null,"token":null,"profilePhotoString":null,"accountNonExpired":true,"credentialsNonExpired":true,"accountNonLocked":true,"active":true,"enabled":false}
}
Output :
Person add callednull
Screenshot :
Sample result
Thread Name: Thread Group 2-5
Sample Start: 2017-06-29 15:17:11 IST
Load time: 6
Connect Time: 0
Latency: 6
Size in bytes: 237
Sent bytes:0
Headers size in bytes: 205
Body size in bytes: 32
Sample Count: 1
Error Count: 1
Data type ("text"|"bin"|""): text
Response code: 415
Response message: Unsupported Media Type
Response headers:
HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Language: en
Content-Length: 1048
Date: Thu, 29 Jun 2017 09:47:11 GMT
Connection: close
HTTPSampleResult fields:
ContentType: text/html;charset=utf-8
DataEncoding: utf-8
Request:
POST http://127.0.0.1:8080/person/add/
POST data:
{"person":{"id":0,"username":"testemail#gmail.com","firstName":"test","cleanCacheFlag":false,"googleDrive":false,"dropbox":false,"evernoteConsumed":false,"statusChangeTimeStamp":null,"useCalendar":false,"newsletterFlag":false,"tourSteps":null,"profession":null,"notiz":null,"telePhone":null,"lastVisitedBoards":null,"leftGroup":null,"optionalEmail":null,"facebookLink":null,"xingLink":null,"linkedinLink":null,"lastOnlineTimestamp":null,"userRole":null,"homePage":null,"excelImportQuota":0,"toEmail":null,"code":null,"authorities":null,"role":null,"newpassword":null,"token":null,"profilePhotoString":null,"accountNonExpired":true,"credentialsNonExpired":true,"accountNonLocked":true,"active":true,"enabled":false}
}
[no cookies]
Request Headers:
Connection: close
Content-Length: 717
Content-Type: application/x-www-form-urlencoded
Change header Content-Type in HTTP Header Manager from:
Content-Type: application/x-www-form-urlencoded
To:
Content-Type: application/json
Shouldn't you just have an #RequestBody annotation on person ?
public String addPerson(#RequestBody Person person);
Well, there is a typo or copy-paste issue in your JMeter request
Also your JMeter configuration might be missing HTTP Header Manager configured to send Content-Type header with the value of application/json

Retrofit 2: 400 Bad Request when having body

I am trying to perform a status update PUT request. The following example returns 200 in Postman:
URL:
http://www.example.com/users/3/status?seId=1&dt=2016-11-01T00:00:00Z
HEADERS:
Content-Type:application/json
charset:utf-8
Authorization:Bearer LONG_TOKEN_HERE
BODY:
{ "status": 1 }
This is the structure of my Retrofit 2 request:
#PUT("users/{id}/status")
Call<Void> updateEventStatus(#Header("Authorization") String token,
#Path("id") int id,
#Query("seId") int seId,
#Query("dt") String dateTime,
#Body Status status);
The request's URL is the same as in Postman and so are the headers, so I suspect it is related to the body. Status is just a wrapping class with a single int field named status, which I created by following this answer (I did the same with credentials and it works well). I also tried making the status in body of type int but it results in Bad Request as well.
Any idea what could be the difference between the Postman request and the Retrofit 2 request? Thanks!
EDIT: This is the originalRequest in Retrofit 2:
Request{method=PUT, url=http://example.com/api/users/3/status?seId=0&dt=2016-10-04T05:30:00Z, tag=null}
headers: Authorization: Bearer LONG_TOKEN_HERE
contentType: application/json; charset=UTF-8
content:
0 = 123
1 = 34
2 = 115
3 = 116
4 = 97
5 = 116
6 = 117
7 = 115
8 = 34
9 = 58
10 = 51
11 = 125
Translated content:
{"status":3}
Eventually, it was a server-side bug (I received a false seId at first, and then tried to PUT using an seId that doesn't exist).

Can't get Set-Cookie header from http response

I am developing a small web content scraper . Part of the code is to send a http request and get the cookie from the response header, so it can be set in the subsequent request.
The code to get the cookies is like this:
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
request.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
request.setHeader("Accept-Encoding","gzip,deflate,sdch");
if(cookie!=null)
{
request.setHeader("Cookie", cookie);
}
request.setHeader("Accept-Language","en-US,en;q=0.8,zh-CN;q=0.6");
request.setHeader("Cache-Control", "max-age=0");
request.setHeader("Connetion", "keep-alive");
request.setHeader("Host", "www.booking.com");
request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/32.0.1700.76 Safari/537.36");
try {
HttpResponse response = client.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
System.out.println(statusCode);
//get all headers
Header[] headers = response.getAllHeaders();
for (Header header : headers) {
System.out.println("Key : " + header.getName()
+ " ,Value : " + header.getValue());
}
System.out.println("----------------------------------------------------------");
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The url I used to test is http://www.booking.com/hotel/il/herods-hotels-spa.html#tab-reviews
The result printed is like this:
200
Key : Server ,Value : nginx
Key : Date ,Value : Mon, 03 Feb 2014 05:15:41 GMT
Key : Content-Type ,Value : text/html; charset=UTF-8
Key : Connection ,Value : keep-alive
Key : Cache-Control ,Value : private
Key : Vary ,Value : User-Agent, Accept-Encoding
Key : Set-Cookie ,Value : bkng=11UmFuZG9tSVYkc2RlIyh9YdMHS7ByVcpJ6zdHwCKMHsY37i1DyVPCutMoSY%2F9OR7ixF74JFUj1%2BJ3pF8ntbVX55kLQJvNnfE6Qco2NDwnHPzomws7z40vIxLRgwBTWU9CTbAN3zZqJGksaPN3GqHpSWJ%2BMIKlI5hQN6ZcJnKsU3rR9KXmRVS4plyPQf4gqmsjR131%2BtuuBiULzmDsKzejJZg%2BFgWWUOWS71bCxUGvJbeBBo1HRmUVmigKDEyHylYplnhKkriMof25dYccWyLQoBjIyUL4QZWr58O5D7fKPHDYWSY9y7k%2Bxfk7irIsyKdu%2B0owjpGp2%2BncNdphtqPZqdpeCyky1ReSjWVQ4QuZemceNGmfZGwxm%2BQxu0%2BkBEsJA5zY%2BoqulR8MJIBKZpFqsuvbeDZ9r5UJzl5c%2Fqk7Vw5YU1I%2FQunbw7PHra7IaGp6%2BmHnH2%2BeyiMDhAjWL769ebuwG2DhrgfB6eI0AGZE%2F6T0uA4j7bxA%2FwUdhog6yOu%2FSeTkPl%2FTAiIetVyKLfT1949ggWKfk1kGzmjnowOlZzPbxr1L%2FAifBjInWZ6DreY1Mr2A3%2BfjFYaHJYnS8VpB%2BZappBpGXBUVfHe%2FQ7lbDwNd6TCCzigpsb17LtvFYsb3JiZ%2BQFF82ILNwWFKz6B1xxEEbCRVoq8N%2FcXXPStyGSwApHZz%2Bew6LNI7Hkd2rjB1w3HenUXprZWR3XiWIWYyhMAbkaFbiQV2LThkl2Dkl%2FA%3D; domain=.booking.com; path=/; expires=Sat, 02-Feb-2019 05:15:41 GMT; HTTPOnly
Key : X-Recruiting ,Value : Like HTTP headers? Come write ours: booking.com/jobs
However when I uploaded this small program to my server, and ran it, the result became:
200
Key : Server ,Value : nginx
Key : Date ,Value : Mon, 03 Feb 2014 05:14:14 GMT
Key : Content-Type ,Value : text/html; charset=UTF-8
Key : Connection ,Value : keep-alive
Key : Cache-Control ,Value : private
Key : Vary ,Value : User-Agent, Accept-Encoding
Key : X-Recruiting ,Value : Like HTTP headers? Come write ours: booking.com/jobs
The Set-Cookie header disappeared and my subsequent requests to other content pages within the same site(which are supposed to be loaded by a javascript in the first page I requested) all returned 400 error which I guess is because the cookie missing.
I can't figure out why, and the differences between my pc and the server that I know are:
My pc is running Windows 7 and actually has a Chrome browser, while the server is running Linux and doesn't have any actual browser.
The ip addresses are different.
Other than these, I can't think of any yet.
Any suggestion or advice to solve this problem will be appreciated. Thank you.
set-cookie is a forbidden response header name, you can't read it using browser-side JavaScript
developer.mozilla.org
Browsers block frontend JavaScript code from accessing the Set Cookie header, as required by the Fetch spec, which defines Set-Cookie as a forbidden response-header name that must be filtered out from any response exposed to frontend code.

Categories