I'm trying to fetch data from post request in react, but I can't get nothing back, the response it's ok and save the data in the database, after that I need to return a token in react but I can't understand why It does't work.
I tried a lot ot cros but nothing change.
Here the request in react:
save(registerDTO) {
fetch('http://localhost:8080/api/auth/register',{ method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': '*/*', 'Access-Control-Allow-Credentials': true},body: JSON.stringify( registerDTO )})
.then(data => console.log(data))
.catch(error=>console.warn(error))
}
}
In the ispection on google chrome everything works but I can't see the response even on there
there isn't nothing in the response option.
This is my code on spring boot side:
#PostMapping("/register")
public ResponseEntity<Map<String,String>> registerHandler(#RequestBody RegisterDTO registerDTO) {
log.info("User: {}",registerDTO);
return ResponseEntity.ok(registerService.saveUser(registerDTO));
}
In postman everything work fine, I can't even get the error message in react.
I tried to add a lot of cors code:
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000","192.168.1.7:3000"));
configuration.setAllowedMethods(Arrays.asList("GET","POST","DELETE"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
// #Bean
// public WebMvcConfigurer corsConfigurer() {
// return new WebMvcConfigurer() {
// #Override
// public void addCorsMappings(CorsRegistry registry) {
// registry.addMapping("/**").allowedOrigins("http://localhost:3000/**");
// }
// };
// }
// #Bean
// public CorsConfigurationSource corsConfigurationSource() {
// UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
// return source;
// }
and I added this annotation in the restcontroller:
#CrossOrigin(origins = "http://localhost:3000")
you missing:
.then(res=> res.json())
in your fetch code.
Related
Service Code
public ResponseEntity<String> getSessionCookie() {
logger.info("Get Cookies");
var cookie1 = ResponseCookie.from("ASP.NET_SessionId_Wx", appConfig.getSessionId()).httpOnly(false).path("/").secure(false).build();
var cookie2 = ResponseCookie.from("WX-XSRF-TOKEN", appConfig.getToken()).httpOnly(false).path("/").build();
return ResponseEntity.ok().header(HttpHeaders.SET_COOKIE, cookie1.toString())
.header(HttpHeaders.SET_COOKIE, cookie2.toString()).build();
}
Angular Code
Service
public getSession(): Observable<any> {
return this.http.get<any>('//example.com/getSessionCookie/', {withCredentials: true});
}
Component
this.ds.getSession().subscribe((res) => {
console.log('Get Session Header: ', res.headers);
})
}
Able to view the cookies in Postman and Chrome Dev Tools (Network tab - Response Headers)
Added CORS config to SprinBoot App
public class CorsConfiguration implements WebMvcConfigurer
{
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOriginPatterns("*").allowedHeaders("*").allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE");
}
}
I figured it out.
The issue was with the 'Set-Cookie'.
Angular is unable to read the 'Set-Cookie' header. Changed the header key to some other name and added the same in exposedHeaders as well.
Worked like a Charm:).
Thanks.
I have added the necessary dependencies for spring open feign like mentioned in https://github.com/OpenFeign/feign-form and followed the mentioned configuration for feign-client.
Whenever I sent the post request with content-type as application/x-www-form-urlencoded. The request body is not generated properly.
EmailClient.java
#FeignClient(name = "email", url = "localhost:3000",
configuration = EmailClientConfiguration.class)
public interface EmailClient {
#PostMapping(value = "/email/send")
ResponseDto sendEmail(#RequestBody Map<String, String> requestBody);
}
This is my client configuration Class:
public class EmailClientConfiguration {
#Bean
public RequestInterceptor requestInterceptor(Account<Account> account) {
return template -> {
template.header("Content-Type", "application/x-www-form-urlencoded");
};
}
#Bean
public OkHttpClient client() {
return new OkHttpClient();
}
#Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
#Bean
public Decoder feignDecoder() {
return new JacksonDecoder();
}
#Bean
public Encoder feignFormEncoder () {
return new SpringFormEncoder(new JacksonEncoder());
}
}
Map<String, String> requestBody = new HashMap<>();
requestBody.put("username", "xyz");
requestBody.put("email", "xyz#gmail.com");
requestBody.put("key", "xxx");
when I called the sendEmail method in interface, the requester headers are set correctly but the request body is sent as
{"{\n \"key\" : \"xxx\",\n \"email\" : \"xyz#gmail.com\",\n \"username\" : \"xyz\"\n}"
Can someone please help on this. Why request body is sent like this. And also the request body is not hidden in the server side though content-type is application/x-www-form-urlencoded.
It works fine after adding consumes.
#FeignClient(name = "email", url = "localhost:3000",
configuration = EmailClientConfiguration.class)
public interface EmailClient {
#PostMapping(value = "/email/send", consumes = "application/x-www-form-urlencoded")
ResponseDto sendEmail(#RequestBody Map<String, String> requestBody);
}
Request URL: ******
Request Method: OPTIONS
Status Code: 403
Remote Address: ****
Referrer Policy: no-referrer-when-downgrade
For the post call browser showing it as OPTIONS.
The following is the server code:
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
System.out.println("onboard cors");
registry.addMapping("/**").allowedMethods("GET", "PUT", "POST", "DELETE", "OPTIONS").allowedOrigins("*").allowedHeaders("*");
}
};
}
The above code is working fine when I directly call the respective service.
But getting 'invalid cors request' error by calling the service through zuul api gateway.
Any suggestions plz?
Your browser first checks if POST method is safe to send to the endpoint and if yes then does POST request. You should provide permissions to OPTIONS method and respond it with Allow: GET, HEAD, POST and all should be okay. I faced that problem while working with Python, so it's all about CORS and does not depend on platform.
See more information about it here
The following solution worked for me.
Add the below code in zuul project:
#Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new org.springframework.web.filter.CorsFilter(source));
bean.setOrder(0);
return bean;
}
Adding corsfilter code in all microservices is not required.
Reference: https://stackoverflow.com/a/46277194/4132466
Am using Auth0 for my authentication service. I have a web application communicating with a springboot API. Am trying to authenticate access to my API resource using Auth0 jwt token. Below is my implementation.
My Auth0 JS web application
var options = {
allowAutocomplete: true,
autoclose: true,
container: 'login-auth',
theme: {
logo: 'http://palermoinn.com/wp-content/uploads/2015/12/pullman_palermoinn.png',
primaryColor: '#009688',
foregroundColor: "#009688",
labeledSubmitButton: false,
},
auth: {
audience: 'https://xxx.auth0.com/userinfo',
responseType: 'token id_token',
params: {
state: 'into',
scope: 'openid email profile roles'
}
},
redirectUri: window.location.href,
languageDictionary: {
title: "Log In"
}
};
// console.log(constants.CLIENT_ID + " or " + constants.VERIFY_URL + " or " + constants.TYPE_GET);
var lock = new Auth0Lock(
'CLIENT_ID',
'xxx.auth0.com',
options
);
if (token == null && profile == null) {
lock.show();
} else {
var HEADER = {
token: token,
timeStamp: new Date().getTime(),
access: profile
}
console.log(JSON.stringify(HEADER));
/**
* This request would first request a token from the Auth0 Server
* The token is returned and that token is used to access API resource
*/
network.call(constants.STATS_URL + '1', constants.TYPE_GET, {}, token);
// window.location.href = "dashboard.html";
}
From my springboot Web security configuration I implemented the following
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST"));
configuration.setAllowCredentials(true);
configuration.addAllowedHeader("Authorization");
configuration.addAllowedHeader("cache-control");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors();
JwtWebSecurityConfigurer
.forRS256(AUTH_AUD, AUTH_ISSUER)
.configure(http)
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/v1/clients/stats/{userId}").authenticated();
}
My question now is Springboot web config I designed won't auth my request with the token I passed in the header. It keeps giving me an 401 unauthorized response. What am I doing wrong?
I am getting a problem while implementing multipart file upload using spring boot 1.5.2.
Here is the situation, I have a mapping to handle file upload process.While I start the spring server, it starts without any error. The problem is that I would either able to upload the file perfectly fine or I would get null on all attribute in FileBucket object.
This situation would stay forever if I do not shutdown the server.
If it could upload, it would upload fine for the rest of the time.
If not, it won't work until I restart the server(likely more than one
time)
Here is the mapping.
#RequestMapping(value = {"/api/upload"}, method = RequestMethod.POST)
public ResponseEntity<Map<String, Integer>> upload(#Valid FileBucket fileBucket, BindingResult result) throws IOException {
Session session = sessionFactory.openSession();
User user = (User) session.load(User.class, getUserId());
Map<String, Integer> model = new HashMap<String, Integer>();
if (result.hasErrors()) {
System.out.println("validation errors");
System.out.println(result);
session.close();
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
} else {
int documentId = saveDocument(fileBucket, user);
model.put("documentId", documentId);
session.close();
return new ResponseEntity<Map<String, Integer>>(model, HttpStatus.OK);
}
}
And the FileBucket object
public class FileBucketConversation {
private MultipartFile file;
public MultipartFile getFile() {
return file;
}
public void setFile(MultipartFile file) {
this.file = file;
}
}
I have tried few ways to implement file upload, and still having the same situation.
Using StandardServletMultipartResolver.
#Bean(name = "multipartResolver")
public StandardServletMultipartResolver resolver() {
return new StandardServletMultipartResolver();
}
Using CommonsMultipartResolver v1.3.2.
#Bean(name="multipartResolver")
public CommonsMultipartResolver multipartResolver () {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(MAX_FILE_SIZE);
return resolver;
}
overriding MultipartFilter
#Bean
#Order(0)
public MultipartFilter multipartFile() {
MultipartFilter multipartFilter = new MultipartFilter();
multipartFilter.setMultipartResolverBeanName("multipartResolver");
return multipartFilter;
}
Enable spring.http.multipart in properties file
spring.http.multipart.enabled=true
spring.http.multipart.max-file-size=20Mb
spring.http.multipart.max-request-size=20Mb
I really have no clue where to start looking. The problem happen occasionally, it do not happen every time I start the server but most of the time. Hoping some one could help me.
Thank you.
I had the same problem, this is my solution:
In application.yml:
spring:
http:
multipart:
enabled: false
In configuration:
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
...
#Bean
public MultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
In RestController:
#PostMapping(value = "api/upload", consumes = "multipart/form-data")
public void enablePurchase(#RequestHeader HttpHeaders headers,
FileBucketConversation fileBucketConversation) {
...
}
Important:
In your client don't use any header to define the Content-type or boundary. I'm using Angular 4 and when I remove these headers from my code it works (I only set the User token):
/* DON'T USE THIS:
let boundary = "ABDCE";
headers.append("Content-type", "multipart/form-data;boundary=" + boundary);
headers.append("enctype", "multipart/form-data;boundary=" + boundary);
headers.append("boundary", boundary);
*/
I hope this help you.
Update for Spring Boot 2 and Spring 5
spring.http.multipart.enabled is deprecated, so forget about it.
Registering my own beans for MultipartConfigElement or MultipartResolver broke it for me.
I ended up with a #PostMapping method with a single parameter, #RequestPart(name = "file") MultipartFile file. Adding a parameter #RequestHeader HttpHeader headers helped me make sure the client was sending the required header Content-Type with a boundary.
I'm using a Node client with the form-data library and node-fetch. Here's the client code:
const formData = new FormData();
const fileMetadata = {filename: fileName, contentType: 'image/png', knownLength: fs.statSync(pathToFile)};
const formData.append('file', fs.createReadStream(pathToFile), fileMetadata);
fetch(url, {method: 'POST', body: formData});