커머스시스템

Spring Boot로 Google & Kakao 로그인 완벽 구현하기

클라우드준 2024. 11. 26. 14:09

Java와 Spring Boot로 OAuth2 기반 소셜 로그인을 구현하는 방법을 알아보세요! Google 및 Kakao 연동부터 JWT 기반 인증까지 단계별로 상세히 설명합니다.

 

목차

       


      Java로 구현하는 OAuth2 소셜 로그인: 단계별 가이드

      현대의 웹 애플리케이션에서 사용자 인증은 필수적인 요소입니다. 하지만 매번 새로운 계정을 생성하고 비밀번호를 기억해야 하는 과정은 사용자에게 불편을 줄 수 있습니다. 특히, 여러 서비스와 플랫폼을 운영하는 기업이라면 사용자 경험을 개선하고 이탈률을 줄이기 위해 더 효율적인 인증 방식을 고민하게 됩니다.

       

      OAuth2 기반 소셜 로그인은 이러한 문제를 해결하는 강력한 도구입니다. Google, Kakao, Naver와 같은 소셜 플랫폼과 연동하여 사용자가 기존 계정을 활용해 간편하게 로그인할 수 있도록 지원합니다. 이 글에서는 Java와 Spring Boot를 활용하여 OAuth2 소셜 로그인을 단계별로 구현하는 방법을 알아보겠습니다.

       

      로그인 화면

       


      1. OAuth2 소셜 로그인 시스템 설계: 흐름과 원리

      OAuth2는 사용자의 인증 정보를 안전하게 처리하기 위한 표준 프로토콜로, 주로 Authorization Code Grant Type 방식을 사용합니다. 이 방식은 클라이언트 애플리케이션이 민감한 사용자 데이터를 직접 다루지 않고, 인증 서버를 통해 간접적으로 처리하도록 설계되었습니다.소셜 로그인 시스템의 기본 흐름은 다음과 같습니다:

      1. 사용자가 애플리케이션의 로그인 버튼을 클릭하면, Google 또는 Kakao와 같은 소셜 플랫폼으로 리다이렉트됩니다.
      2. 사용자는 해당 플랫폼에서 인증(아이디/비밀번호 입력)을 완료하고 애플리케이션에 권한을 부여합니다.
      3. 인증 성공 시, 소셜 플랫폼은 애플리케이션에 Authorization Code를 반환합니다.
      4. 애플리케이션은 이 코드를 사용해 Access Token을 요청하고 발급받습니다.
      5. 발급된 Access Token으로 사용자 정보를 조회하고, 이를 데이터베이스에 저장하거나 업데이트합니다.

      이러한 설계를 통해 사용자는 별도의 계정을 생성하지 않아도 기존 소셜 계정을 활용해 간편하게 로그인할 수 있습니다.

       

      흐름을 알았으면 이에 맞춰 설계를 진행해 보겠습니다. 

       

      OAuth2 소셜 로그인 시스템 설계

      OAuth2는 Authorization Code Grant Type 방식을 주로 사용하며, 다음과 같은 흐름으로 동작합니다:

      1. 사용자가 로그인 요청
        사용자가 클라이언트 애플리케이션에서 "Google로 로그인" 또는 "Kakao로 로그인" 버튼을 클릭합니다.
      2. 소셜 플랫폼으로 리다이렉트
        클라이언트는 사용자를 Google, Kakao 등의 인증 서버로 리다이렉트합니다.
      3. 사용자 인증 및 권한 승인
        사용자가 소셜 플랫폼에서 아이디/비밀번호를 입력하고 애플리케이션에 권한을 부여합니다.
      4. Authorization Code 발급
        소셜 플랫폼은 인증 성공 시 클라이언트 애플리케이션으로 Authorization Code를 반환합니다.
      5. Access Token 요청 및 발급
        클라이언트는 Authorization Code를 사용해 Access Token을 요청하고 이를 발급받습니다.
      6. 사용자 정보 조회
        Access Token을 사용하여 소셜 플랫폼에서 사용자 정보를 가져옵니다.
      7. 사용자 정보 저장 및 세션 생성
        사용자 정보를 데이터베이스에 저장하거나 업데이트하고, 애플리케이션 세션 또는 JWT 토큰을 생성하여 인증 상태를 유지합니다.

       

      2. Spring Boot로 OAuth2 구현: 단계별 설정

      OAuth2 소셜 로그인을 구현하려면 먼저 Google 및 Kakao와 같은 플랫폼에서 클라이언트 ID와 시크릿 키를 생성해야 합니다. 이후 Spring Boot 프로젝트를 구성하고 보안 설정을 추가합니다.

       

      1>프로젝트 초기화 및 의존성 추가
      Spring Initializr에서 프로젝트를 생성한 후 spring-boot-starter-oauth2-client와 spring-boot-starter-security 의존성을 추가합니다.

       

      2>소셜 플랫폼 설정
      Google Cloud Console과 Kakao Developers에서 OAuth 클라이언트 ID 및 시크릿 키를 생성하고 리디렉션 URI를 설정합니다(예: http://localhost:8080/login/oauth2/code/google).

       

      3>Spring Security 구성

      SecurityConfig 클래스를 작성하여 OAuth2 로그인을 활성화하고 사용자 정보를 처리하는 서비스를 등록합니다:

      @Configuration
      @EnableWebSecurity
      public class SecurityConfig extends WebSecurityConfigurerAdapter {
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              http.csrf().disable()
                  .authorizeRequests()
                      .antMatchers("/", "/login", "/oauth/**").permitAll()
                      .anyRequest().authenticated()
                  .and()
                  .oauth2Login()
                      .defaultSuccessUrl("/home");
          }
      }

       

      4>사용자 정보 처리
      OAuth 로그인이 완료되면 사용자 정보를 데이터베이스에 저장하거나 업데이트하는 로직을 작성해야 합니다:

      @Service
      public class CustomOAuth2UserService extends DefaultOAuth2UserService {
          @Override
          public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
              OAuth2User oAuth2User = super.loadUser(userRequest);
              String email = oAuth2User.getAttribute("email");
              // 사용자 정보 저장 로직 추가
              return oAuth2User;
          }
      }

       

      3. JWT 기반 인증으로 확장하기


      OAuth2 로그인이 성공한 후에는 JWT(Json Web Token)를 발급하여 세션리스(stateless) 인증 구조를 구현할 수 있습니다. JWT는 서버가 별도의 세션 관리를 하지 않아도 되므로 확장성과 성능 측면에서 유리합니다.

      1>JWT 토큰 생성
      사용자의 이메일 또는 고유 식별자를 기반으로 JWT를 생성합니다:

      public String createToken(String email) {
          return Jwts.builder()
                     .setSubject(email)
                     .setIssuedAt(new Date())
                     .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 1일 유효
                     .signWith(SignatureAlgorithm.HS512, "secretKey")
                     .compact();
      }

       

       

      2>JWT 검증 및 인증 필터 추가

       클라이언트가 API 요청 시 Authorization 헤더에 JWT를 포함하여 전송하면, 서버는 이를 검증하여 요청을 처리합니다:

      public String createToken(String email) {
          return Jwts.builder()
                     .setSubject(email)
                     .setIssuedAt(new Date())
                     .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 1일 유효
                     .signWith(SignatureAlgorithm.HS512, "secretKey")
                     .compact();
      }

      3>API 보안 강화

      JWT 기반 인증은 RESTful API 설계에 적합하며, 사용자 세션 관리 없이도 안전한 인증 환경을 제공합니다.

      public Claims validateToken(String token) {
          return Jwts.parser()
                     .setSigningKey("secretKey")
                     .parseClaimsJws(token)
                     .getBody();
      }

       

      단계별 상세 가이드

      위 내용을 조금 더 상세하게 정리해서 작성하겠습니다.

      OAuth2 소셜 로그인은 사용자 인증을 간소화하고 보안을 강화하며 사용자 경험을 크게 개선할 수 있는 기술입니다. 아래는 Java와 Spring Boot를 활용하여 OAuth2 소셜 로그인 시스템을 구축하는 구체적인 단계별 가이드입니다.

       

      1단계: 프로젝트 초기화 및 의존성 설정

      1.1 Spring Boot 프로젝트 생성

      • Spring Initializr(https://start.spring.io/) 사용하여 프로젝트를 생성합니다.
      • 필요한 의존성을 선택합니다:
        • Spring Web: 웹 애플리케이션 개발을 위한 기본 의존성.
        • Spring Security: 보안 및 인증 기능 제공.
        • OAuth2 Client: OAuth2 인증 기능 지원.
        • Spring Data JPA: 데이터베이스 연동.
        • H2 Database (또는 MySQL): 데이터베이스 연동.

      1.2 Gradle 또는 Maven 의존성 추가

      build.gradle 파일에 다음 의존성을 추가합니다:

      dependencies {
          implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
          implementation 'org.springframework.boot:spring-boot-starter-security'
          implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
          implementation 'com.h2database:h2'
          implementation 'com.nimbusds:nimbus-jose-jwt:9.22' // JWT 처리 라이브러리
      }

      2단계: 소셜 플랫폼 설정

      OAuth2 소셜 로그인을 구현하려면 Google, Kakao 등의 플랫폼에서 클라이언트 ID와 시크릿 키를 생성해야 합니다.

       

      2.1 Google OAuth 설정

      1. Google Cloud Console에 접속하여 새 프로젝트를 생성합니다.
      2. API 및 서비스 > 사용자 인증 정보로 이동하여 OAuth 클라이언트 ID를 생성합니다.
      3. 리디렉션 URI를 설정합니다:
        • 예: http://localhost:8080/login/oauth2/code/google
      4. 클라이언트 ID와 클라이언트 시크릿 키를 복사합니다.

      2.2 Kakao OAuth 설정

      1. Kakao Developers에 접속하여 애플리케이션을 생성합니다.
      2. 앱 설정 > 플랫폼에서 리디렉션 URI를 추가합니다:
        • 예: http://localhost:8080/login/oauth2/code/kakao
      3. REST API 키를 복사합니다.

      3단계: Spring Boot 설정

      3.1 application.yml 구성

      Google과 Kakao의 OAuth 클라이언트 정보를 application.yml 파일에 등록합니다.

      spring:
        security:
          oauth2:
            client:
              registration:
                google:
                  client-id: <GOOGLE_CLIENT_ID>
                  client-secret: <GOOGLE_CLIENT_SECRET>
                  scope: profile, email
                  redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
                kakao:
                  client-id: <KAKAO_CLIENT_ID>
                  client-secret: <KAKAO_CLIENT_SECRET>
                  scope: account_email
                  redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
              provider:
                kakao:
                  authorization-uri: https://kauth.kakao.com/oauth/authorize
                  token-uri: https://kauth.kakao.com/oauth/token
                  user-info-uri: https://kapi.kakao.com/v2/user/me

      4단계: Spring Security 구성

      4.1 SecurityConfig 클래스 작성

      Spring Security를 구성하여 OAuth2 로그인을 활성화하고 사용자 정보를 처리하는 서비스를 등록합니다.

      @Configuration
      @EnableWebSecurity
      public class SecurityConfig extends WebSecurityConfigurerAdapter {
      
          @Autowired
          private CustomOAuth2UserService customOAuth2UserService;
      
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              http.csrf().disable()
                  .authorizeRequests()
                      .antMatchers("/", "/login", "/oauth/**").permitAll()
                      .anyRequest().authenticated()
                  .and()
                  .oauth2Login()
                      .userInfoEndpoint()
                          .userService(customOAuth2UserService) // 사용자 정보 로드 서비스 등록
                      .and()
                      .defaultSuccessUrl("/home"); // 로그인 성공 후 리다이렉트 URL
          }
      }

       

      5단계: 사용자 정보 처리 서비스 구현

      OAuth 로그인이 완료된 후 사용자 정보를 데이터베이스에 저장하거나 업데이트하는 로직을 구현합니다.

      5.1 CustomOAuth2UserService 작성

      사용자 정보를 처리하는 서비스 클래스를 작성합니다.

      @Service
      public class CustomOAuth2UserService extends DefaultOAuth2UserService {
      
          @Autowired
          private UserRepository userRepository;
      
          @Override
          public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
              OAuth2User oAuth2User = super.loadUser(userRequest);
      
              // 제공자 정보 (Google, Kakao 등)
              String provider = userRequest.getClientRegistration().getRegistrationId();
              String providerId = oAuth2User.getName();
      
              // 사용자 정보 가져오기
              String email = oAuth2User.getAttribute("email");
              String name = oAuth2User.getAttribute("name");
      
              // 데이터베이스 저장 또는 업데이트
              User user = userRepository.findByEmail(email)
                      .orElseGet(() -> new User(email, name, provider, providerId));
              user.update(name);
              userRepository.save(user);
      
              return new DefaultOAuth2User(
                      Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")),
                      oAuth2User.getAttributes(),
                      "email");
          }
      }

       

      6단계: JWT 토큰 발급 및 인증

      로그인 성공 후 JWT 토큰을 발급하여 클라이언트가 API 요청 시 사용할 수 있도록 합니다.

      6.1 JWT 생성

      JWT 토큰을 생성하는 유틸리티 클래스를 작성합니다.

      public class JwtTokenProvider {
      
          private final String secretKey = "secretKey";
      
          public String createToken(String email) {
              return Jwts.builder()
                         .setSubject(email)
                         .setIssuedAt(new Date())
                         .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 1일 유효
                         .signWith(SignatureAlgorithm.HS512, secretKey)
                         .compact();
          }
      
          public Claims validateToken(String token) {
              return Jwts.parser()
                         .setSigningKey(secretKey)
                         .parseClaimsJws(token)
                         .getBody();
          }
      }

       

      7단계: 데이터베이스 설계

      7.1 User 엔티티 작성

      사용자 정보를 저장할 엔티티 클래스를 작성합니다.

      @Entity
      public class User {
      
          @Id
          @GeneratedValue(strategy = GenerationType.IDENTITY)
          private Long id;
      
          private String email;
          private String name;
          private String provider; // Google, Kakao 등 제공자 정보
          private String providerId;
      
          public User(String email, String name, String provider, String providerId) {
              this.email = email;
              this.name = name;
              this.provider = provider;
              this.providerId = providerId;
          }
      
          public void update(String name) {
              this.name = name;
          }
      }

       

      8단계: 테스트 및 디버깅

      8.1 애플리케이션 실행

      • http://localhost:8080/으로 접속하여 Google 또는 Kakao 로그인 버튼을 클릭합니다.
      • 로그인 성공 후 /home으로 리다이렉트되며 사용자의 이름과 이메일이 표시됩니다.

      8.2 디버깅 포인트

      • Access Token 요청 실패 시 리디렉션 URI가 정확한지 확인하세요.
      • 사용자 정보가 제대로 저장되지 않을 경우 CustomOAuth2UserService의 매핑 로직을 점검하세요.

       


       

       

      마무리

      OAuth2 소셜 로그인은 사용자 경험 개선과 보안 강화를 동시에 실현할 수 있는 강력한 솔루션입니다. Java와 Spring Boot를 활용하면 Google, Kakao 등 다양한 소셜 플랫폼과 손쉽게 통합할 수 있으며, JWT를 통해 세션리스 아키텍처로 확장 가능합니다.통합 로그인을 성공적으로 구축하려면 다음 사항을 기억하세요:

      • 각 소셜 플랫폼의 OAuth 설정과 리디렉션 URI 구성을 정확히 확인하세요.
      • Spring Security와 CustomOAuth2UserService를 활용해 사용자 정보를 안전하게 처리하세요.
      • JWT 기반 인증으로 확장하여 확장성과 성능을 최적화하세요.

      이제 여러분의 애플리케이션에 OAuth2 기반 소셜 로그인을 도입해 보세요! 이를 통해 사용자 만족도를 높이고 서비스 경쟁력을 강화할 수 있을 것입니다.