2024. 4. 23. 12:20ㆍFull Stack Course 풀스택과정/SPRING
배울내용:
SpringBoot - OAuth2
OAuth2 로 구글 로그인
스프링부트 토큰 발급받기
구글 클라우드 콘솔
OAuth 서비스 구현하기
구글 로그인 만들기
스프링 부트 구글로그인 연동
스프링 부트 구글 로그인 연결
구글 클라우드 콘솔인 https://cloud.google.com/cloud-console
여기로 로그인 한 상태로 들어가서 아래를 클릭
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 설정파일 작성
'Full Stack Course 풀스택과정 > SPRING' 카테고리의 다른 글
SpringBoot 게시글 기본 업로드 VS TOAST UI Editor 로 업로드 (0) | 2024.04.24 |
---|---|
SpringBoot - OAuth2 로 구글 로그인 (2) OAuth2 실행테스트 (0) | 2024.04.23 |
Intellij 로 만든 jar 파일 AWS 서버 구축 (0) | 2024.04.09 |
[ QueryDSL ] java: Attempt to recreate a file for type 오류 해결 (1) | 2024.04.01 |
SPRING_TIP Spring Legacy Project 가 제대로 안 만들어져요 2 (0) | 2024.03.06 |