iku8log

Webエンジニアのタダのメモ。

【Spring Security & axios】異なるオリジン間での認証とcookie保持について

※コードは全て載せていません。ただのメモ

以下の通り開発をしている。

フロントにはvueを使用しているが、vueに限った話ではないので割愛。

httpリクエストのツールとしてaxiosを使用しています。

問題

異なるオリジン間(今回だとlocalhost:8080とlocalhost:3000になる)で、認証を行う場合、 localhost:3000でセッションIDをcookieに保持することができなかった。

正確には、localhost:8080側のcookieにセッションIDが保持されていた。

CSRFとかCORSを意思しないと行けない。でも難しい...。

したいこと

localhost:3000からaxiosを使用し、localhost:8080に対してログイン処理のリクエストを送る。 localhost:8080側でid,passを検証し認可。 また、セッションIDの発行を行い、localhost:3000のcookieに発行したセッションIDをセットする。

解決策

  • フロントでwithCredentialsを有効にする
  • サーバ側も↑を許可するための設定を行う。
// フロント側
  public async login() {
    const params = new URLSearchParams()
    params.append('email', this.email)
    params.append('password', this.password)

    await axios.post(
      'localhost:8080/login',
      params,
      {
        withCredentials: true // ここが重要
      }
    ).then((result) => {
      window.console.log(result)
      window.console.log('成功')
    }).catch((result) => {
      window.console.log(result)
      window.console.log('失敗')
    })
  }
// サーバ側
    private CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedMethod("POST");
        corsConfiguration.addAllowedOrigin("http://localhost:3000");
        corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
        corsConfiguration.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource();
        corsSource.registerCorsConfiguration("/login", corsConfiguration);

        return corsSource;
    }

サーバ側はcorsの設定を色々していますが、 corsConfiguration.setAllowCredentials(true);この部分が重要

あとは 、corsConfigurationSourceをspring securtyに設定する。

        http
            .authorizeRequests()
                .anyRequest()
                .authenticated()
            .and()
                .formLogin()
                .loginProcessingUrl("/login").permitAll()
                .usernameParameter("email")
                .passwordParameter("password")
                .successHandler(new SuccessHandler())
            .and()
                .csrf()
                    .ignoringAntMatchers("/login")
            .and()
                .cors()
                .configurationSource(corsConfigurationSource());

とりあえず詰まっていた部分を載せました。 過不足多いと思いますので、参考程度してください。

csrfもcorsもムズイ。というかspring securityが難しい。