I have the following Java Spring REST API method:
#RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity login(#RequestBody LoginRequest request) {
request.getSession(true);
LoginResponse res = this.authService.login(request);
return new ResponseEntity<>(res, HttpStatus.OK);
}
When called using Postman or from a FireFox browser, I can clearly see the "Set-Cookie" header:
Yet, when I'm using console.log to print the response in Angular, I don't see this header:
This is the REST call in Angular:
this.http.post<Login>(this.url, this.loginRequest, {
headers: AuthService.getHeaders(),
observe: 'response',
withCredentials: true
}).subscribe(
response => {
console.log(response);
});
I did add withCredentials: true and observe: 'response' to the request call as suggested, and I do get the whole response, but without the cookie.
What I want to do is to get a cookie after a successful login, which will be delivered with any request afterwards for authentication in the server.
Thanks for the help!
Seems that browsers do not share the cookies to the client if it's not https. I had to follow this guide in order to serve the application in https mode, and then I was able to see the cookie in the server side.
Related
What is the difference with UniRest and Spring RestTemplate which is giving back a 400 Bad Request with apparently the same header and body sent ?
I try to reach the HubSpot API to create a BlogPost, but using RestTemplate I have a 400 Bad Request error, and using UniRest works alright (returns an OK response). However, I do not want to include a library just to make one REST call: I'd rather stick to RestTemplate.
The request data I need to send
HttpMethod: POST
URL: https://api.hubapi.com/content/api/v2/blog-posts?hapikey=*****************
Header: Content-Type: application/json
Body: (represented by a class instance as blogpostSendPost further down)
{
"name": "My first API blog post!",
"content_group_id": 351076997
}
Using RestTemplate
Setting up the request:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<BlogpostSendPost> request = new HttpEntity<>(blogpostSendPost, headers);
log(request.toString());
//LOG PRINT: <BlogpostSendPost(name=My first API blog post!, content_group_id=351076997),[Content-Type:"application/json"]>
OR in JSON
The .json() method converts my object in Json like you can see in the logs
HttpEntity<String> request = new HttpEntity<>(blogpostSendPost.toJson(), headers);
log(request.toString());
//LOG PRINT: <{"name":"My first API blog post!","content_group_id":"351076997"},[Content-Type:"application/json"]>
With .postForObject(): 400 Bad Request
BlogpostResponsePost answer = restTemplate.postForObject(
"https://api.hubapi.com/content/api/v2/blog-posts?hapikey=***********",
request,
BlogpostResponsePost.class);
With .exchange(): 400 Bad Request
BlogpostResponsePost answer = restTemplate.exchange(
"https://api.hubapi.com/content/api/v2/blog-posts?hapikey=**********",
HttpMethod.POST,
request,
BlogpostResponsePost.class);
Using UniRest: OK
HttpResponse<JsonNode> resp = Unirest
.post("https://api.hubapi.com/content/api/v2/blog-posts?hapikey=**********")
.header("Content-Type", "application/json")
.body(blogpostSendPost)
.asJson();
I am using PostMan to call my REST SpringBoot Application which is using theses Services : when I am calling the HubSpot API directly from PostMan it works fine, just like with UniRest lib.
Thanks for your help guys !!
Please refer https://community.hubspot.com/t5/APIs-Integrations/Getting-400-Bad-Request-when-trying-to-add-a-Blog-Post/td-p/306532
Instead of converting request object to json, pass request object directly. It worked for me.
// TRY 1: CONTACTS - RestTemplate - OK - contact is created (API V1)
HttpEntity request1 = new HttpEntity<>(contactSendList, headers);
ContactResponseInformations answer1 = restTemplate
.postForObject(
HubSpotConfiguration.URL_CREATE_CONTACT,
request1,
ContactResponseInformations.class);
log.info(answer1.toString()); // OK
I have implemented OAuth2 in Spring boot. It works well when testing it in JUnit but I always get unauthorized when I try the API in postman.
test function in JUnit:
private String obtainAccessToken(String username, String password) throws Exception {
final MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "password");
params.add("client_id", CLIENT_ID);
params.add("username", username);
params.add("password", password);
ResultActions result = mockMvc.perform(post("/oauth/token")
.params(params)
.with(httpBasic(CLIENT_ID, CLIENT_SECRET))
.accept(CONTENT_TYPE))
.andExpect(status().isOk())
.andExpect(content().contentType(CONTENT_TYPE));
String resultString = result.andReturn().getResponse().getContentAsString();
JacksonJsonParser jsonParser = new JacksonJsonParser();
return jsonParser.parseMap(resultString).get("access_token").toString();
}
I tried following APIs in postman:
POST type http://localhost:8080/oauth/token with content type application/json
in Body section I selected raw and JSON :
{
"grant_type":"password",
"client_id":"clientIdPassword",
"username":"a",
"password":"a"
}
It showed 401 Unauthorized. Then I also tried like this :
Post type with content type application/json, http://localhost:8080/oauth/token?grant_type=password&client_id=clientIdPassword&username=a&password=a. This also showed 401 Unauthorized.
My question is how can I set MultiValueMap as parameter in Postman?
you should use authorization tab of postman to send auth headers along with request body however you like.
PFA sample image
When you send the request via POSTMAN tool, select the type of HTTP method (POST, PUT, DELETE), then select the "raw" option in "Body" tab and then just add the JSON of the Map in it. Make sure you have selected "Content-type" as "application/json" in "Headers" .
I have a question on how to fetch response body in Jersey client when server returns some sample text with status code 401. Sample service is setup as follows:
#GET
#Path("test401withcontent")
public Response get401TestWithContent()
{
return Response.status(401).entity("return some text").build();
}
On the client side (using Jersey 1.17) ClientResponse.getEntity prints null.
Noticed that content-length of headers has the right number (16 in this case.)
Is there a different way to get response when return code is 401?
Have deployed you method to my test web site and used below client got currect response.
Client client = ClientBuilder.newClient();
//System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
Response response = client.target(
"http://jerseyexample-ravikant.rhcloud.com/rest/jws/test401withcontent").
request().get(); System.out.println(response.readEntity(String.class));
So I used answer for this question as my tutorial for token based authentication. But I still have a problem with setting up authorization header.
In my authenticateUser method I tried to set up a bearer header, here's th code
#POST
#Path("/users/authentication")
#Produces("application/json")
#Consumes("application/x-www-form-urlencoded")
public Response getUsers(#FormParam("username") String username,
#FormParam("password") String password){
try{
if(userDao.existUser(username, password)){
User uUser = new User(userDao.getUser(username, password));
uUser.setToken(userDao.issueToken());
uUser.setTokenExpDate();
userDao.updateUser(uUser);
Response response = Response.ok(userDao.getUser(uUser.getId()).getToken())
.header(HttpHeaders.AUTHORIZATION, "Bearer "+userDao.getUser(uUser.getId()).getToken())
.build();
System.out.println(response.getHeaderString(HttpHeaders.AUTHORIZATION));
return response;
}
}catch(Exception e){
return Response.status(Response.Status.UNAUTHORIZED).build();
}
return null;
}
As you can see I'm setting it on response variable and it's there. But once I go to secured method and my AuthenticationFilter activates I find out that the header that i get from requestContext is null. How do I sent token to this header properly in this situation? Here's my full code
The header must be included by the client, not by the server. The general flow is this
1)the client authenticates in your Service with credentials, then the server builds a token and returns it to the client, which stores the token in a secure storage
2)the client performs a request and include the token in the header.
POST /yourservice
Authorization: Bearer thetoken
3)The server checks the header, extracts the token and validate it
I am having some issues trying to receive a response message from a Spring RESTful web service to an AngularJS client.
I am using ResponseEntity<String> to return a response to the client. This works when only returning a status code but AngularJS fails with Unexpected token R when I send a response message in the body.
What am I doing wrong?
return new ResponseEntity<String>(HttpStatus.OK);
But this does not work:
return new ResponseEntity<String>("Report was updated successfully", HttpStatus.OK);
AngularJs code:
$http.get(url, header)
.success(function(data, status, headers, config) {
// some logic
}).error(function(resp, status) {
// some logic
});
Response:
Is Angular expecting JSON or HTML/text back?
I've experienced issues in the past returning text/javascript or application/json instead of text/html. It looks like Angular is expecting JSON or JSONP in that instance, hence the Unexpected Token R (which is the first letter of your response string).
I could give a more precise answer, but I'd need to also know if you're using JSONP vs JSON, etc.