いくつかの理由で、この単純な問題が多くの開発者をブロックしています。私はこの単純なことで何時間も苦労しました。この問題は多くの次元と同じです。
- CORS(異なるドメインおよびポートでフロントエンドとバックエンドを使用している場合。
- バックエンドCORS構成
- Axiosの基本認証構成
CORS
開発のための私のセットアップは、localhost:8081で実行されているvuejs webpackアプリケーションとlocalhost:8080で実行されているSpring Bootアプリケーションを使用しています。そのため、フロントエンドからREST APIを呼び出そうとする場合、適切なCORS設定なしに、ブラウザーがSpringバックエンドから応答を受信できるようにする方法はありません。CORSを使用して、最新のブラウザーが持っているクロスドメインスクリプト(XSS)保護を緩和できます。私がこれを理解しているように、ブラウザはSPAをXSSによる攻撃から保護しています。もちろん、StackOverflowに対するいくつかの回答は、XSS保護を無効にするクロムプラグインを追加することを提案しましたが、これは実際に機能します。
バックエンドCORS構成
Spring BootアプリでCORSを設定する方法は次のとおりです。
CorsFilterクラスを追加して、クライアント要求への応答に適切なヘッダーを追加します。Access-Control-Allow-OriginとAccess-Control-Allow-Headersは、基本認証で最も重要なものです。
public class CorsFilter implements Filter {
...
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
response.setHeader("Access-Control-Allow-Origin", "http://localhost:8081");
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
**response.setHeader("Access-Control-Allow-Headers", "authorization, Content-Type");**
response.setHeader("Access-Control-Max-Age", "3600");
filterChain.doFilter(servletRequest, servletResponse);
}
...
}
Spring WebSecurityConfigurationAdapterを拡張する構成クラスを追加します。このクラスでは、CORSフィルターを挿入します。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
@Bean
CorsFilter corsFilter() {
CorsFilter filter = new CorsFilter();
return filter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(corsFilter(), SessionManagementFilter.class) //adds your custom CorsFilter
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/api/login")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.authenticationProvider(getProvider());
}
...
}
CORSに関連するものをコントローラーに配置する必要はありません。
フロントエンド
次に、フロントエンドで、Authorizationヘッダーを使用してaxiosクエリを作成する必要があります。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<p>{{ status }}</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
status: ''
},
created: function () {
this.getBackendResource();
},
methods: {
getBackendResource: function () {
this.status = 'Loading...';
var vm = this;
var user = "aUserName";
var pass = "aPassword";
var url = 'http://localhost:8080/api/resource';
var authorizationBasic = window.btoa(user + ':' + pass);
var config = {
"headers": {
"Authorization": "Basic " + authorizationBasic
}
};
axios.get(url, config)
.then(function (response) {
vm.status = response.data[0];
})
.catch(function (error) {
vm.status = 'An error occured.' + error;
})
}
}
})
</script>
</body>
</html>
お役に立てれば。