lap*_*rof 19 rest spring http spring-boot angular
我正在尝试为我的 Web 应用程序创建用户管理 API。当我从前端向后端发送 API 调用时,发生 cors 错误。cors问题如何解决?我已经阅读了很多线程,但我没有取得任何进展。
createUser() API 调用后出错
Access to XMLHttpRequest at 'http://localhost:8080/user/create'
from origin 'http://localhost:4200' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check:
Redirect is not allowed for a preflight request.
Run Code Online (Sandbox Code Playgroud)
角标头.config.ts
export const HTTP_OPTIONS = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Access-Control-Allow-Credentials' : 'true',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PATCH, DELETE, PUT, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With',
})
};
Run Code Online (Sandbox Code Playgroud)
角度休息-user.service.ts
public createUser() {
return this.httpClient.post(this.USER_ENDPOINT + 'create', HTTP_OPTIONS);
}
Run Code Online (Sandbox Code Playgroud)
SpringConfig.class
@Configuration
@EnableWebMvc
public class SpringConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
Run Code Online (Sandbox Code Playgroud)
SpringSecurityConfig.class
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and().oauth2Client()
.and().oauth2Login();
}
}
Run Code Online (Sandbox Code Playgroud)
UserRestController.class
@PostMapping("/user/create")
@ResponseBody
@ResponseStatus(HttpStatus.CREATED)
public void createUser(Principal principal) throws UserAlreadyExistsException {
userServiceFacadeImpl.createUser(principal.getName());
}
Run Code Online (Sandbox Code Playgroud)
网络留言
更新 20.06.19
private createUser() {
const headersObject = new HttpHeaders();
this.oktaAuth.getAccessToken().then( (value) => {
headersObject.append('Authorization', 'Bearer ' + value);
headersObject.append('Content-Type', 'application/json');
const httpOptions = {
headers: headersObject
};
this.httpClient.post('http://localhost:8080/user/' + 'create', null, httpOptions);
});
}
Run Code Online (Sandbox Code Playgroud)
您可能需要在 Spring Boot 端配置 CORS。请在您的项目中添加以下类。
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class WebConfig implements Filter,WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
System.out.println("WebConfig; "+request.getRequestURI());
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With,observe");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Expose-Headers", "Authorization");
response.addHeader("Access-Control-Expose-Headers", "responseType");
response.addHeader("Access-Control-Expose-Headers", "observe");
System.out.println("Request Method: "+request.getMethod());
if (!(request.getMethod().equalsIgnoreCase("OPTIONS"))) {
try {
chain.doFilter(req, res);
} catch(Exception e) {
e.printStackTrace();
}
} else {
System.out.println("Pre-flight");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Access-Control-Expose-Headers"+"Authorization, content-type," +
"USERID"+"ROLE"+
"access-control-request-headers,access-control-request-method,accept,origin,authorization,x-requested-with,responseType,observe");
response.setStatus(HttpServletResponse.SC_OK);
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
要将令牌附加到每个请求,您可以创建一个拦截器,如下所示。
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = window.localStorage.getItem('tokenKey'); // you probably want to store it in localStorage or something
if (!token) {
return next.handle(req);
}
const req1 = req.clone({
headers: req.headers.set('Authorization', `${token}`),
});
return next.handle(req1);
}
}
Run Code Online (Sandbox Code Playgroud)
由于原始端口 4200 与 8080 不同,因此在 Angular 发送创建(PUT)请求之前,它将向服务器发送 OPTIONS 请求,以检查所有方法以及所有访问控制都已到位。服务器必须使用允许的方法和允许的来源列表来响应该 OPTIONS 请求。
由于您使用的是 Spring Boot,因此简单的解决方案是添加".allowedOrigins("http://localhost:4200");"
在你的 spring 配置中,类
@Configuration
@EnableWebMvc
public class SpringConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://localhost:4200");
}
}
Run Code Online (Sandbox Code Playgroud)
然而,更好的方法是编写一个过滤器(拦截器),为每个响应添加必要的标头。
如果您使用Spring 作为后端服务器,尤其是使用Spring Security,那么我通过放入http.cors();该configure方法找到了一个解决方案。该方法看起来像这样:
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests() // authorize
.anyRequest().authenticated() // all requests are authenticated
.and()
.httpBasic();
http.cors();
}
Run Code Online (Sandbox Code Playgroud)
CORS 标头应从服务器发送。如果你使用 PHP,它将是这样的:
header('Access-Control-Allow-Origin: your-host');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: your-methods like POST,GET');
header('Access-Control-Allow-Headers: content-type or other');
header('Content-Type: application/json');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
163724 次 |
| 最近记录: |