0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Spring で Google ログインURLを作る方法

Posted at

Google Login Urlを作る方法

前提

有名な Social Login Provider は Spring によって管理されているため元々は Login URL を作るとかの作業はいらないです。
ですが、今回作るアプリケーションではフロントエンドでは client_idclient_secret も何も管理していなく全部バックエンドで管理しています。

要件

  • ユーザが /a, /abcどちらにいてもログインボタンを押してログインモーダルが表示されてログインしたら、その後、元のページに戻る必要があります。
  • 全てバックエンドで制御していますので redirect で元のページに戻す必要があります。

実装

フロントエンドから currentUr を貰って state にセットします。

package jp.co.kopher.backendkotlin.controller

import jakarta.servlet.http.HttpServletRequest
import jp.co.kopher.backendkotlin.response.AuthLoginResponse
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/v1")
class OAuth2Controller(
    private val clientRegistrationRepository: ClientRegistrationRepository,
) {

    @GetMapping("/login")
    fun login(@RequestParam("google") currentUrl: String, request: HttpServletRequest): AuthLoginResponse {
        val resolver = DefaultOAuth2AuthorizationRequestResolver(
            clientRegistrationRepository,
            DEFAULT_AUTHORIZATION_REQUEST_BASE_URI
        )
        val authRequest = resolver.resolve(request, "google").let {
            OAuth2AuthorizationRequest.from(it)
                .state(currentUrl) // JWTを生成してstateにセットするのをお勧めします。
                .build()
        }

        return AuthLoginResponse(authRequest.authorizationRequestUri)
    }
}

上でセットした state の値は google によって call back される時に query parameter としてセットされてきますのでそれを抽出します。

package jp.co.kopher.backendkotlin.controller

import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.springframework.security.core.Authentication
import org.springframework.security.web.authentication.AuthenticationSuccessHandler
import org.springframework.stereotype.Component

@Component
class OAuth2SuccessHandler : AuthenticationSuccessHandler {
    override fun onAuthenticationSuccess(
        request: HttpServletRequest?,
        response: HttpServletResponse?,
        authentication: Authentication?
    ) {
        val currentUri = request?.getParameter("state") ?: "/"
        response?.sendRedirect("http://localhost:3000/$currentUri")
    }
}

Google 認証成功後呼ばれる Handler として OAuth2SuccessHandler を登録します。

package jp.co.kopher.backendkotlin.config

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.AuthenticationSuccessHandler

@Configuration
class SecurityConfig(
    private val oauth2SuccessHandler: AuthenticationSuccessHandler,
) {

    @Bean
    fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
        http.oauth2Login {
            it.successHandler(oauth2SuccessHandler)
        }
        return http.build()
    }
}

これで終わりです!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?