SpringBoot - OAuth2 로 구글 로그인 (1) (토큰 발급받기)

2024. 4. 23. 12:20Full Stack Course 풀스택과정/SPRING

728x90

배울내용: 

SpringBoot - OAuth2

OAuth2 로 구글 로그인

스프링부트 토큰 발급받기

구글 클라우드 콘솔

OAuth 서비스 구현하기 

구글 로그인 만들기

스프링 부트 구글로그인 연동

스프링 부트 구글 로그인 연결 

 

구글 클라우드 콘솔인 https://cloud.google.com/cloud-console 

 

Google Cloud 콘솔  |  Cloud Console - 웹 UI 관리

콘솔에서 데이터 분석, VM, 데이터 스토어, 데이터베이스, 네트워킹, 개발자 서비스 등 클라우드 애플리케이션의 모든 것을 관리하세요.

cloud.google.com

 

여기로 로그인 한 상태로 들어가서 아래를 클릭 

 

 

 

 

 

 

 

 

 

 

Google-MapAPI 이런게 있는데 이건 필자가 이전에 사용하려고 만든것이니 글자가 틀리더라도 무시하고

클릭하자 

 

 

 

 

 

 

 

NEW Project (새 프로젝트) 를 열어주자 

 

 

 

 

 

그리고 Project name(프로젝트 이름) 을 "springboot-developer" 라고 짓고 

조직, 위치는 없는걸로하고 CREATE 클릭 

 

 

 

 

 

 

그러면 조금있다가 완성이 되면서 왼쪽에 API 및 서비스(APIs and Services) > 사용자 인증정보(Credential) 을 클릭후

사용자 인증정보로가면 위와 같이 CONFIGURE CONSENT SCREEN(동의 화면 구성) 이뜬다 클릭하자 

 

 

 

 

 

 

 

그리고  User Type 을 내부 또는 외부를 선택하는데 External(외부) 를 클릭후 CREATE 

 

 

 

 

 

 

다시 앱 이름(App name) 을 이전과 같이 springboot-developer 로해주고

유저 지정 이메일(User support email), 개발자 연락처 정보는 본인 이메일로 해주면 된다. 

 

그리고 저장 후 계속(save and continue) 

 

 

 

 

 

범위 추가 또는 삭제(ADD OR REMOVE SCOPES) 클릭 그리고 아래처럼 2 개 클릭한다 

 

 

 

 

기본 이메일 주소확인을 위한것과

Google 에서 내 개인정보를 나와 연결 을 클릭한다 

 

 

 

 

그리고 저장

 

 

 

 

 

 

 

 

완성되면 이런창이 뜬다 

 

 

 

 

 

그리고 1. 사용자 인증정보(Credentials) > 2. 사용자 인증정보 만들기(CREATE CREDENTIALS) > 3.OAuth 클라이언트 ID(OAuth client ID) 를 클릭하자 

 

 

 

 

 

그리고 위와 1,2,3 처럼 1에는 웹 애플리케이션(Web application)  2 이름(Name) 에는 이전과 동일하게

3번에는 http://localhost:8080/login/oauth2/code/google 를 넣어준다(이건 개개인마다 틀림) 

 

 

 

 

그러면 클라이언트 ID (Client ID)  와 클라이언트 보안 비밀번호 (Client secret) 가 보이게 된다 

 

 

이거를 기존에 작성하던 Springboot 에 application.yml 

 

red(빨간색) 과 blue(파란색)에 각각 클라이언트 ID (Client ID)  와 클라이언트 보안 비밀번호 (Client secret) 

를 넣어준다 

security:
  oauth2:
    client:
      registration:
        google:
          client-id: red
          client-secret: blue
          scope:
            - email
            - profile

 

 

그리고 dependency 에 oauth2 를 추가 

implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'

 

 

 

 

 

그리고 아래와 같은 코드를 추가해준다 

package com.codehows.diary.util;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.util.SerializationUtils;

import java.util.Base64;

public class CookieUtil {
    public static void addCookie(HttpServletResponse response, String name, String value, int maxAge){
        Cookie cookie = new Cookie(name, value);
        cookie.setPath("/");
        cookie.setMaxAge(maxAge);
        response.addCookie(cookie);
    }

    //쿠키 삭제
    public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String name){
        Cookie[] cookies = request.getCookies();
        if(cookies ==null){
            return;
        }

        for(Cookie cookie : cookies){
            if(name.equals(cookie.getName())){
                cookie.setValue("");
                cookie.setPath("/");
                cookie.setMaxAge(0);
                response.addCookie(cookie);
            }
        }
    }

    // 쿠키값 변환
    public static String serialize(Object obj){
        return Base64.getUrlEncoder()
                .encodeToString(SerializationUtils.serialize(obj));
    }


    //객체 변환
    public static <T> T deserialize(Cookie cookie, Class<T> cls){
        return cls.cast(
                SerializationUtils.deserialize(
                        Base64.getUrlDecoder().decode(cookie.getValue())
                )
        );
    }

}

 

 

 

 

OAuth 서비스 구현하기 

 

 

package com.codehows.diary.Domain;

import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;
import java.util.List;

@Table(name = "users")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Entity
public class User implements UserDetails {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id" , updatable = false)
    private Long id;

    @Column(name = "email", nullable = false, unique = true)
    private String email;

    @Column(name = "password")
    private String password;

    @Column(name = "nickname" , unique = true)
    private String nickname;



    @Builder
    public User(String email, String password, String nickname){
        this.email=email;
        this.password=password;
        this.nickname= nickname;

    }

    public User update(String nickname){
        this.nickname = nickname;
        return this;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities(){
        return List.of(new SimpleGrantedAuthority("user"));
    }

    @Override
    public String getUsername() {
        return email;
    }

    @Override
    public String  getPassword() {
        return password;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }


    @Override
    public boolean isEnabled() {
        return true;
    }


}

 

 

OAuth 관련 키 저장하는 코드를 넣어준다 

 

 

 

 

그리고 OAuth2UserCustomService.java 를 만들어서 아래처럼 추가한다 

 

package com.codehows.diary.Config.oauth;

import com.codehows.diary.Domain.User;
import com.codehows.diary.Repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;

import java.util.Map;

@RequiredArgsConstructor
@Service
public class OAuth2UserCustomService extends DefaultOAuth2UserService {

    private final UserRepository userRepository;

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        OAuth2User user = super.loadUser(userRequest); // ❶ 요청을 바탕으로 유저 정보를 담은 객체 반환
        saveOrUpdate(user);

        return user;
    }

    // ❷ 유저가 있으면 업데이트, 없으면 유저 생성
    private User saveOrUpdate(OAuth2User oAuth2User) {
        Map<String, Object> attributes = oAuth2User.getAttributes();

        String email = (String) attributes.get("email");
        String name = (String) attributes.get("name");

        User user = userRepository.findByEmail(email)
                .map(entity -> entity.update(name))
                .orElse(User.builder()
                        .email(email)
                        .nickname(name)
                        .build());

        return userRepository.save(user);
    }
}

 

 

다음부턴 2편부터 OAuth2 설정파일 작성 

728x90