Vue + Spring SecurityでJWT認証を使う
やること
フロントエンドをVue、バックエンドをSpringで構成したアプリケーションで、JWTによる認証を行う
やりかた
バックエンド側の設定
以下の記事によくまとまっていたので参考にしました。
VueでAPIを呼び出した際にCORSで弾かれてしまったので、WebSecurityConfigに以下設定を追加しています。
フロントエンドをdev serverで起動しているので動作確認しているのでそのせいかも?
フロントエンド側でヘッダーに格納されるAuthorization情報が取得できなかったので expose 設定に追加しています。
それ以外は一般的なCORS設定です。
@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { // 省略 @Override protected void configure(HttpSecurity http) throws Exception { http .cors().configurationSource(this.corsConfigurationSource()) // 省略 } private CorsConfigurationSource corsConfigurationSource() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedMethod(CorsConfiguration.ALL); corsConfiguration.addAllowedHeader(CorsConfiguration.ALL); corsConfiguration.addExposedHeader("Authorization"); corsConfiguration.addAllowedOrigin("http://hogehoge.com"); corsConfiguration.setAllowCredentials(true); UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource(); corsSource.registerCorsConfiguration("/**", corsConfiguration); return corsSource; } }
フロントエンドの設定
ログイン処理の中でヘッダー情報のトークンをvuexのストアに保存します。
axiosの実装は下のJavascriptファイルを参考にしてください。
vuexへの保存は一般的な実装なので省略します。
// ログイン処理を行うメソッド内 const res = await HttpClient.getAxios().post('/api/login', { "userName" : this.loginId, "password" : this.password } ); const jwt: string = res.headers.authorization; this.$store.commit('saveJwt', jwt); // 省略
HTTP通信をするのにaxiosというモジュールを使っているので、これを介してHTTPクライアントを作成するときに
ヘッダー情報がセットされるようにしています。(ログインで保存しておいたvuexのストアから取得)
※初回リクエストとなるloginではjwtは空になりますが、サーバー側でloginAPIのみトークン認証がかからないようにしています。
import axios from 'axios' import store from 'store/index'; const URL = 'http://localhost:8081'; const instance = axios.create({ baseURL: URL, timeout: 10000, headers: { 'Content-Type': 'application/json' } }); export default class HttpClient { public static getAxios() { instance.defaults.headers.common['Authorization'] = 'Bearer ' + store.getters.jwt; return instance; } }
残作業
セッションのような状態を管理しないので、多重ログイン制御がこれ単体ではできない。
セッションの場合はRedisを使っていたので同じようにRedisに有効なJWTを保存してバリデーションをかける。