Skip to content

Commit

Permalink
소셜 로그인 구현
Browse files Browse the repository at this point in the history
HeeSung98 committed Nov 20, 2023
1 parent 836c79b commit 9b6adc7
Showing 7 changed files with 162 additions and 14 deletions.
2 changes: 2 additions & 0 deletions user/build.gradle
Original file line number Diff line number Diff line change
@@ -38,6 +38,8 @@ dependencies {
testImplementation 'org.springframework.security:spring-security-test'
//추가
implementation 'mysql:mysql-connector-java:8.0.31'
//추가
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
}

dependencyManagement {
44 changes: 34 additions & 10 deletions user/src/main/java/com/weather/user/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,49 @@
package com.weather.user.config;

import com.weather.user.security.filter.ApiCheckFilter;
import com.weather.user.security.handler.LoginSuccessHandler;
import com.weather.user.security.service.AuthUserDetailsService;
import com.weather.user.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@RequiredArgsConstructor
public class SecurityConfig {
private final AuthUserDetailsService authUserDetailsService;

@Bean
PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }

// @Bean
// public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
// http.authorizeHttpRequests((auth) -> auth
// .requestMatchers("/test", "/hello").permitAll()
// .requestMatchers("/").hasRole("user"));
// http.formLogin((login) -> login.loginPage("/login"));
// http.csrf((csrf) -> csrf.disable());
//
// return http.build();
// }
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.authorizeHttpRequests((auth) -> auth
.requestMatchers("/**").permitAll());
http.csrf((csrf) -> csrf.disable());
http.formLogin(login -> login.successHandler(loginSuccessHandler()));
http.oauth2Login(login -> login.successHandler(loginSuccessHandler()));
http.logout(Customizer.withDefaults());
http.rememberMe(rememberMe -> rememberMe.tokenValiditySeconds(60*60*24*60).userDetailsService(authUserDetailsService));

http.addFilterBefore(apiCheckFilter(), UsernamePasswordAuthenticationFilter.class);

return http.build();
}

@Bean
public LoginSuccessHandler loginSuccessHandler() {
return new LoginSuccessHandler(passwordEncoder());
}

@Bean
public ApiCheckFilter apiCheckFilter() {
return new ApiCheckFilter();
}
}
Original file line number Diff line number Diff line change
@@ -8,22 +8,28 @@
import org.springframework.security.core.userdetails.User;

import java.util.Collection;
import java.util.Map;

@Log4j2
@Getter
@Setter
@ToString
public class AuthUserDTO extends User {
private String email, password;
private String email, password, name, nickname, image;

private boolean fromSocial, status;

public AuthUserDTO(String username, String password, boolean fromSocial, boolean status,
Map<String, Object> attributes;

public AuthUserDTO(String username, String password, String name, String nickname,String image, boolean fromSocial, boolean status,
Collection<? extends GrantedAuthority> authorities) {
super(username, password, authorities);
this.email = username;
this.fromSocial = fromSocial;
this.password = password;
this.name = name;
this.nickname = nickname;
this.image = image;
this.fromSocial = fromSocial;
this.status = status;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.weather.user.security.filter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

public class ApiCheckFilter extends OncePerRequestFilter {
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.weather.user.security.handler;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.log4j.Log4j2;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.io.IOException;

@Log4j2
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
private RedirectStrategy redirectStrategy;
private PasswordEncoder passwordEncoder;

public LoginSuccessHandler(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
log.info("ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ");
log.info("인증에 성공했습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ public class AuthUserDetailsService implements UserDetailsService {

@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
log.info("ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ");
log.info("email: " + email);

Optional<User> optionalUser = userRepository.findByEmail(email, false);
@@ -34,7 +35,8 @@ public UserDetails loadUserByUsername(String email) throws UsernameNotFoundExcep
log.info("user: " + user.getPassword());

AuthUserDTO authUserDTO = new AuthUserDTO(
user.getEmail(), user.getPassword(), user.isFromSocial(), user.isStatus(),
user.getEmail(), user.getPassword(), user.getImage(), user.getName(), user.getNickname(),
user.isFromSocial(), user.isStatus(),
user.getRoleSet().stream().map((role) ->
new SimpleGrantedAuthority("Role_" + role.name())).collect(Collectors.toSet())
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.weather.user.security.service;

import com.weather.user.entity.User;
import com.weather.user.entity.UserRole;
import com.weather.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.security.crypto.password.PasswordEncoder;
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.Optional;

@Log4j2
@Service
@RequiredArgsConstructor
public class OAuth2UserDetailsService extends DefaultOAuth2UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;

@Override
public OAuth2User loadUser(OAuth2UserRequest request) throws OAuth2AuthenticationException {
log.info("ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ");
log.info("request: " + request);

log.info("clientName: " + request.getClientRegistration().getClientName());
log.info("params: " + request.getAdditionalParameters());

OAuth2User oAuth2User = super.loadUser(request);

oAuth2User.getAttributes().forEach((key, value) -> {
log.info(key + ": " + value);
});

User user = saveSocialUser(oAuth2User);

return oAuth2User;
}

private User saveSocialUser(OAuth2User oAuth2User) {
log.info("ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ");
String email = oAuth2User.getAttribute("email");
String image = oAuth2User.getAttribute("picture");
Optional<User> optionalUser = userRepository.findByEmail(email, true);

if(optionalUser.isPresent()) {
return optionalUser.get();
} else {
User socialUser = User.builder()
.email(email)
.password(passwordEncoder.encode("1234"))
.image(image)
.fromSocial(true)
.status(true)
.build();

socialUser.addRole(UserRole.USER);

userRepository.save(socialUser);

return socialUser;
}
}
}

0 comments on commit 9b6adc7

Please sign in to comment.