ํ๋ฆ ์ดํดํ๊ธฐ
spring boot์์ ๊ตฌ๊ธ ์์ ๋ก๊ทธ์ธ ํ๋ ๋ฐฉ๋ฒ์ ๊ธฐ๋ณธ ํ๋ฆ์ ์๋์ ๊ฐ๋ค.
[๊ตฌ๊ธ ๋ก๊ทธ์ธ ํด๋ฆญ]
↓
[๊ตฌ๊ธ ๋ก๊ทธ์ธ → redirect URI๋ก ํ ํฐ ๋ฐํ]
↓
[Spring Security๊ฐ ํ ํฐ ๋ฐ์์ ์ฌ์ฉ์ ์ ๋ณด ํ๋]
↓
[์๋ ๋ก๊ทธ์ธ or DB ์ฌ์ฉ์ ๋ฑ๋ก]
์ฒ์์ ์ค์ ํ ๊ฒ๋ ๋ง๊ณ ํ ๊ฒ๋ ๋ง์์ ๊ต์ฅํ ๊ท์ฐฎ๊ณ ์ง๋ฃจํ์ง๋ง ํ๋ฒ ์ ๋๋ก ์ตํ๋๋ฉด ๋ค๋ฅธ ์์ ๋ก๊ทธ์ธ๋ ๋น์ทํ ๊ตฌ์กฐ๊ธฐ ๋๋ฌธ์ ์ง๊ธ ์ง์์ ์จ๋จน์ผ๋ฉด ๋๋ค.
ํด๋ผ์ด์ธํธ ์์ด๋ ๋ง๋ค๊ธฐ
Google ํด๋ผ์ฐ๋ ํ๋ซํผ
๋ก๊ทธ์ธ Google ํด๋ผ์ฐ๋ ํ๋ซํผ์ผ๋ก ์ด๋
accounts.google.com
ํด๋น ์ฌ์ดํธ์ ์ ์ํ์ฌ ์ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ณ API๋ฐ ์๋น์ค์ ๋ค์ด๊ฐ Oauth ๋์ ํ๋ฉด์ ์ ํํ๋ค.

์์ํ๊ธฐ๋ฅผ ๋๋ฅด๋ฉด ๋ญ๋ญ๋ฅผ ์ ์ผ๋ผ๊ณ ํ๋๋ฐ

๋์ถฉ ์ ์ด์ฃผ๊ณ ์๋ฃํ๋ฉด ๋๊ณ ์๋ OAuth 2.0 ํด๋ผ์ด์ธํธ ID ๋ง๋ค๊ธฐ๋ฅผ ์ ํํ๋ค.


์ฌ๊ธฐ ์น์ธ๋ ๋ฆฌ๋๋ ์ url์ url ์ถ๊ฐ ๋ฒํผ์ ๋๋ฅธํ
http://localhost:8080/login/oauth2/code/google
๋ฅผ ์ ๋ ฅํ๊ณ ๋ง๋ค๊ธฐ๋ฅผ ๋๋ฅธ๋ค.

๊ทธ๋ฌ๋ฉด ์ด๋ ๊ฒ ํด๋ผ์ด์ธํธ id๊ฐ ์์ฑ๋๋ค.
Dependencies ์ถ๊ฐํ๊ธฐ
build.gradle์ dependencies์ ์๋์ฝ๋๋ฅผ ์ถ๊ฐํ๊ณ
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
Properties ์ถ๊ฐํ๊ธฐ
application.properties์๋ ํด๋น ์ค์ ์ ์ถ๊ฐํด์ผ ํ๋ค.
spring.security.oauth2.client.registration.google.client-id=๋ฐ๊ธ๋ฐ์-client-id
spring.security.oauth2.client.registration.google.client-secret=๋ฐ๊ธ๋ฐ์-client-secret
spring.security.oauth2.client.registration.google.scope=profile,email
spring.security.oauth2.client.provider.google.authorization-uri=https://accounts.google.com/o/oauth2/v2/auth
spring.security.oauth2.client.provider.google.token-uri=https://oauth2.googleapis.com/token
spring.security.oauth2.client.provider.google.user-info-uri=https://www.googleapis.com/oauth2/v3/userinfo
spring.security.oauth2.client.provider.google.user-name-attribute=sub
์ฐธ๊ณ ๋ก ๋ฐ๊ธ๋ฐ์ client-secret์ ํธ์ง์ ๋ค์ด๊ฐ๋ฉด ๋์์๋ค.
์ํ๋ฆฌํฐ ์ค์ ํ๊ธฐ
์ด์ ๊ตฌ๊ธ ๋ก๊ทธ์ธ ํ๋ฆ์ ์ฒ๋ฆฌํ ์ํ๋ฆฌํฐ ์ค์ ๋ถํฐ ํด๋ณด์.
๋ชฉํ
- ๊ตฌ๊ธ ๋ก๊ทธ์ธ url ์๋ ์ ๊ณต
- ๋ก๊ทธ์ธ ์ฑ๊ณต ์ ์ฌ์ฉ์ ์ ๋ณด ๋ฐ์์ db ์ ์ฅ ๋ก๊ทธ์ธ ์ฒ๋ฆฌ
- ์ธ์ฆ๋ ์ฌ์ฉ์๋ง ์ฌ์ฉํ ์ ์๋ ํ์ด์ง ๋ถ๋ฆฌ
JPA ์ค์
jpa๋ ์ธ๊บผ๋ผ ์ผ๋จ build.gradle์ dependencies์ ํด๋น ์ฝ๋๋ ์ถ๊ฐํด์ค๋ค.
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
๊ทธ๋ค์ application.properties์ db์ ์์ ๋ณด๋ค jpa์ค์ ๋ ์ถ๊ฐํด์ค๋ค
#PostgreSQL ์ ์ ์ ๋ณด
spring.datasource.url=jdbc:postgresql://localhost:5432/your_db_name
spring.datasource.username=your_db_user
spring.datasource.password=your_db_password
spring.datasource.driver-class-name=org.postgresql.Driver
# JPA ์ค์
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
# ํ์์กด ์ค์ (์ ํ)
spring.jpa.properties.hibernate.jdbc.time_zone=Asia/Seoul

ํด๋๊ตฌ์กฐ๋ ์ด๋ฐ์์ผ๋ก ํด๋จ๋ค.
์ฝ๋ ์ ๊ธฐ
User entity > UserRepository > CustomOath2UserService > SecurityConfig ์์ผ๋ก ๋ง๋ค์ด๋ณด์.
Users
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Users {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
private String nickname;
}
UserRepository
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
}
CustomOauth2UserService
@Service
@RequiredArgsConstructor
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
private final UserRepository userRepository;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2User delegate = new DefaultOAuth2UserService().loadUser(userRequest);
Map<String, Object> attributes = delegate.getAttributes();
// ๊ตฌ๊ธ ์ฌ์ฉ์ ์ ๋ณด์์ email๊ณผ name ๊ฐ์ ธ์ค๊ธฐ
String email = (String) attributes.get("email");
String name = (String) attributes.get("name");
// ์์ผ๋ฉด ์๋ก ์ ์ฅ
User user = userRepository.findByEmail(email)
.orElseGet(() -> userRepository.save(User.builder()
.email(email)
.nickname(name)
.build()));
return new DefaultOAuth2User(
Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")),
attributes,
"email" // attributes ์ค์์ key๋ก ์ฌ์ฉํ ๊ฐ
);
}
}
SecurityConfig
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final CustomOAuth2UserService customOAuth2UserService;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/css/**", "/js/**", "/images/**", "/login").permitAll()
.anyRequest().authenticated()
)
.oauth2Login(oauth -> oauth
.loginPage("/login") // ์ปค์คํ
๋ก๊ทธ์ธ ํ์ด์ง
.defaultSuccessUrl("/dashboard", true)
.userInfoEndpoint(user -> user
.userService(customOAuth2UserService) // ์ฌ์ฉ์ ์ ๋ณด ์ฒ๋ฆฌ ๋ก์ง
)
)
.logout(logout -> logout
.logoutSuccessUrl("/")
.invalidateHttpSession(true)
);
return http.build();
}
}
๋ค์์์๋ ์ด์ ํ๋ก ํธ๋จ์ ์ฐ๊ฒฐํด์ ์ง์ ๋ก๊ทธ์ธ๋๊ฒ ํด๋ณด์~~