From 1d563c35ec27ba148ee78362fd4db5a4f99313e7 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Fri, 11 Oct 2024 20:36:19 +0900 Subject: [PATCH 01/19] =?UTF-8?q?chore:=20#9=20ouath=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20gitingnore=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 772e3ec..264074c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ application.yaml application-dev.yaml application-local.yaml application-jwt.yaml +application-oauth.yaml ### macOS ### .DS_Store From 6b20f7afe6c53dca9c9b9da0a766a65b0f2c5624 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Fri, 11 Oct 2024 23:30:30 +0900 Subject: [PATCH 02/19] =?UTF-8?q?feat:=20#9=20=20OAuth=EB=A5=BC=20?= =?UTF-8?q?=ED=86=B5=ED=95=9C=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OAuth를 통한 로그인 초기구현 완료 추가 정보 입력을 위한 로직 구현이 필요합니다. --- build.gradle | 3 + .../xcellentbe/domain/user/domain/User.java | 22 ++++++- .../domain/repository/UserRepository.java | 1 + .../auth/login/oauth/CustomOAuthUser.java | 28 +++++++++ .../login/oauth/CustomOAuthUserService.java | 63 +++++++++++++++++++ .../auth/login/oauth/GoogleOAuthUserInfo.java | 16 +++++ .../auth/login/oauth/OAuthAttributes.java | 40 ++++++++++++ .../login/oauth/OAuthLoginSuccessHandler.java | 54 ++++++++++++++++ .../global/config/SecurityConfig.java | 12 ++-- 9 files changed, 233 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUser.java create mode 100644 src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUserService.java create mode 100644 src/main/java/com/leets/xcellentbe/global/auth/login/oauth/GoogleOAuthUserInfo.java create mode 100644 src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java create mode 100644 src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthLoginSuccessHandler.java diff --git a/build.gradle b/build.gradle index e50197b..c5a9fa8 100644 --- a/build.gradle +++ b/build.gradle @@ -54,6 +54,9 @@ dependencies { implementation 'io.jsonwebtoken:jjwt-jackson:0.12.6' implementation 'com.auth0:java-jwt:4.4.0' + // OAuth2 + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + // Swagger implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' diff --git a/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java b/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java index 22d6421..e2b3169 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java @@ -7,7 +7,7 @@ import com.leets.xcellentbe.domain.shared.BaseTimeEntity; import com.leets.xcellentbe.domain.shared.UserStatus; - +import com.leets.xcellentbe.domain.user.Role; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -55,6 +55,8 @@ public class User extends BaseTimeEntity { @Column(length = 50) private String email; + private String socialEmail; // 소셜 로그인 이메일 + @Column(length = 20) private String phoneNumber; @@ -75,6 +77,12 @@ public class User extends BaseTimeEntity { @Enumerated(EnumType.STRING) private UserStatus userStatus; + @NotNull + @Column + @Enumerated(EnumType.STRING) + private Role userRole; + + @NotNull @Column(length=4) private int userBirthYear; @@ -88,7 +96,7 @@ public class User extends BaseTimeEntity { private int userBirthDay; @Builder - private User(String customId, String email, String userName, String password, String phoneNumber, String description, int userBirthDay, int userBirthMonth, int userBirthYear) { + private User(String customId, String email, String userName, String password, String phoneNumber, String description, int userBirthDay, int userBirthMonth, int userBirthYear, String socialEmail, Role userRole) { this.customId = customId; this.email = email; this.userName = userName; @@ -96,6 +104,7 @@ private User(String customId, String email, String userName, String password, St this.phoneNumber= phoneNumber; this.description = description; this.userStatus = UserStatus.ACTIVE; + this.userRole = userRole; this.userBirthMonth = userBirthMonth; this.userBirthYear = userBirthYear; this.userBirthDay = userBirthDay; @@ -115,6 +124,15 @@ public static User create(String customId, String email, String userName, String .userBirthDay(userBirthDay) .userBirthYear(userBirthYear) .userBirthMonth(userBirthMonth) + .userRole(Role.USER) + .build(); + } + + public static User socialCreate(String email, String socialEmail) { + return User.builder() + .email(email) + .userRole(Role.GUEST) + .socialEmail(socialEmail) .build(); } diff --git a/src/main/java/com/leets/xcellentbe/domain/user/domain/repository/UserRepository.java b/src/main/java/com/leets/xcellentbe/domain/user/domain/repository/UserRepository.java index 3988549..ed4938f 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/domain/repository/UserRepository.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/domain/repository/UserRepository.java @@ -10,4 +10,5 @@ public interface UserRepository extends JpaRepository { Optional findByEmail(String email); Optional findByCustomId(String customId);; Optional findByRefreshToken(String refreshToken); + } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUser.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUser.java new file mode 100644 index 0000000..5251e18 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUser.java @@ -0,0 +1,28 @@ +package com.leets.xcellentbe.global.auth.login.oauth; + +import org.springframework.security.oauth2.core.user.DefaultOAuth2User; +import org.springframework.security.core.GrantedAuthority; +import java.util.Collection; +import java.util.Map; + +import com.leets.xcellentbe.domain.user.Role; + +import lombok.Getter; + +/** + * DefaultOAuth2User를 상속하고, email과 role 필드를 추가로 가진다. + */ +@Getter +public class CustomOAuthUser extends DefaultOAuth2User { + + private String email; + private Role role; + + public CustomOAuthUser(Collection authorities, + Map attributes, String nameAttributeKey, + String email, Role role) { + super(authorities, attributes, nameAttributeKey); + this.email = email; + this.role = role; + } +} diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUserService.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUserService.java new file mode 100644 index 0000000..41f1f59 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUserService.java @@ -0,0 +1,63 @@ +package com.leets.xcellentbe.global.auth.login.oauth; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.Map; + +import com.leets.xcellentbe.domain.user.domain.User; +import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; + +@Slf4j +@Service +@RequiredArgsConstructor +public class CustomOAuthUserService implements OAuth2UserService { + + private final UserRepository userRepository; + + @Override + public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { + log.info("CustomOAuth2UserService.loadUser() 실행 - OAuth2 로그인 요청 진입"); + + OAuth2UserService delegate = new DefaultOAuth2UserService(); + OAuth2User oAuth2User = delegate.loadUser(userRequest); + + String userNameAttributeName = userRequest.getClientRegistration() + .getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName(); + Map attributes = oAuth2User.getAttributes(); + + OAuthAttributes extractAttributes = OAuthAttributes.of(userNameAttributeName, attributes); + + User createdUser = getUser(extractAttributes); + + return new CustomOAuthUser( + Collections.singleton(new SimpleGrantedAuthority(createdUser.getUserRole().getKey())), + attributes, + extractAttributes.getNameAttributeKey(), + createdUser.getEmail(), + createdUser.getUserRole() + ); + } + + private User getUser(OAuthAttributes attributes) { + User findUser = userRepository.findByEmail(attributes.getGoogleOAuthUserInfo().getEmail()).orElse(null); + + if(findUser == null) { + return saveUser(attributes); + } + return findUser; + } + + private User saveUser(OAuthAttributes attributes) { + User createdUser = attributes.toEntity(attributes.getGoogleOAuthUserInfo()); + return userRepository.save(createdUser); + } +} diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/GoogleOAuthUserInfo.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/GoogleOAuthUserInfo.java new file mode 100644 index 0000000..62735b8 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/GoogleOAuthUserInfo.java @@ -0,0 +1,16 @@ +package com.leets.xcellentbe.global.auth.login.oauth; + +import java.util.Map; + +public class GoogleOAuthUserInfo { + + private final Map attributes; + + public GoogleOAuthUserInfo(Map attributes) { + this.attributes = attributes; + } + public String getEmail() { + return (String) attributes.get("email"); + } + +} diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java new file mode 100644 index 0000000..4fa6982 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java @@ -0,0 +1,40 @@ +package com.leets.xcellentbe.global.auth.login.oauth; + +import lombok.Builder; +import lombok.Getter; + +import java.util.Map; +import java.util.UUID; + +import com.leets.xcellentbe.domain.user.Role; +import com.leets.xcellentbe.domain.user.domain.User; + +@Getter +public class OAuthAttributes { + + private String nameAttributeKey; + private GoogleOAuthUserInfo googleOAuthUserInfo; + + @Builder + private OAuthAttributes(String nameAttributeKey, GoogleOAuthUserInfo googleOAuthUserInfo) { + this.nameAttributeKey = nameAttributeKey; + this.googleOAuthUserInfo = googleOAuthUserInfo; + } + + public static OAuthAttributes of(String userNameAttributeName, Map attributes) { + return OAuthAttributes.builder() + .nameAttributeKey(userNameAttributeName) + .googleOAuthUserInfo(new GoogleOAuthUserInfo(attributes)) + .build(); + } + + public User toEntity(GoogleOAuthUserInfo googleOAuthUserInfo) { + return User.builder() + .email(googleOAuthUserInfo.getEmail()) + .password("password") + .customId("customId") + .userName("userName") + .userRole(Role.GUEST) + .build(); + } +} diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthLoginSuccessHandler.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthLoginSuccessHandler.java new file mode 100644 index 0000000..84f9daa --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthLoginSuccessHandler.java @@ -0,0 +1,54 @@ +package com.leets.xcellentbe.global.auth.login.oauth; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.stereotype.Component; + + +import java.io.IOException; +import java.util.Optional; + +import com.leets.xcellentbe.domain.user.Role; +import com.leets.xcellentbe.domain.user.domain.User; +import com.leets.xcellentbe.domain.user.domain.repository.UserRepository; +import com.leets.xcellentbe.global.auth.jwt.JwtService; + +@Slf4j +@Component +@RequiredArgsConstructor +public class OAuthLoginSuccessHandler implements AuthenticationSuccessHandler { + + private final JwtService jwtService; + private final UserRepository userRepository; + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { + log.info("OAuth2 Login 성공!"); + CustomOAuthUser oAuth2User = (CustomOAuthUser) authentication.getPrincipal(); + Optional user = userRepository.findByEmail(oAuth2User.getEmail()); + // User의 Role이 GUEST일 경우 처음 요청한 회원이므로 회원가입 페이지로 리다이렉트 + if (oAuth2User.getRole() == Role.GUEST) { + String accessToken = jwtService.createAccessToken(oAuth2User.getEmail()); + response.addHeader(jwtService.getAccessHeader(), "Bearer " + accessToken); + response.sendRedirect("/oauth2/sign-up"); // 프론트의 회원가입 추가 정보 입력 폼으로 ��다이렉트 + jwtService.sendAccessAndRefreshToken(response, accessToken, null); + } else { + loginSuccess(response, oAuth2User); // 로그인에 성공한 경우 access, refresh 토큰 생성 + } + } + + private void loginSuccess(HttpServletResponse response, CustomOAuthUser oAuth2User) throws IOException { + String accessToken = jwtService.createAccessToken(oAuth2User.getEmail()); + String refreshToken = jwtService.createRefreshToken(); + response.addHeader(jwtService.getAccessHeader(), "Bearer " + accessToken); + response.addHeader(jwtService.getRefreshHeader(), "Bearer " + refreshToken); + + jwtService.sendAccessAndRefreshToken(response, accessToken, refreshToken); + jwtService.updateRefreshToken(oAuth2User.getEmail(), refreshToken); + } +} diff --git a/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java b/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java index d48a522..3410cb2 100644 --- a/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java +++ b/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java @@ -33,6 +33,7 @@ import com.leets.xcellentbe.global.auth.login.handler.LoginFailureHandler; import com.leets.xcellentbe.global.auth.login.handler.LoginSuccessHandler; import com.leets.xcellentbe.global.auth.jwt.JwtAuthenticationFilter; +import com.leets.xcellentbe.global.auth.login.oauth.OAuthLoginSuccessHandler; @Configuration @EnableWebSecurity @@ -43,6 +44,7 @@ public class SecurityConfig { private final JwtService jwtService; private final UserRepository userRepository; private final ObjectMapper objectMapper; + private final OAuthLoginSuccessHandler oAuthLoginSuccessHandler; @Bean public PasswordEncoder passwordEncoder() { @@ -51,7 +53,7 @@ public PasswordEncoder passwordEncoder() { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - return http + http .formLogin(AbstractHttpConfigurer::disable) .httpBasic(AbstractHttpConfigurer::disable) .cors(withDefaults()) @@ -74,10 +76,12 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { "/swagger/**", "/api/auth/register", "/api/auth/login").permitAll() .anyRequest().authenticated() ) + .oauth2Login(oauth2 -> oauth2.successHandler(oAuthLoginSuccessHandler)); + // .failureHandler(oAuth2LoginFailureHandler) + http.addFilterAfter(customJsonAuthenticationFilter(), LogoutFilter.class); + http.addFilterBefore(jwtAuthenticationFilter(), CustomJsonAuthenticationFilter.class); - .addFilterAfter(customJsonAuthenticationFilter(), LogoutFilter.class) - .addFilterBefore(jwtAuthenticationFilter(), CustomJsonAuthenticationFilter.class) - .build(); + return http.build(); } @Bean From 7e960e6f7540b15d8544ff4631d81e6ddb821063 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Sat, 12 Oct 2024 22:44:52 +0900 Subject: [PATCH 03/19] =?UTF-8?q?feat:=20#9=20OAuth=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 추후 구현 예정 --- .../auth/jwt/JwtAuthenticationFilter.java | 2 +- .../auth/login/oauth/OAuthAttributes.java | 4 +- .../login/oauth/OAuthLoginSuccessHandler.java | 27 ++++++++++- .../global/auth/login/oauth/PasswordUtil.java | 48 +++++++++++++++++++ .../global/config/SecurityConfig.java | 2 +- src/main/resources/static/index.html | 1 + src/main/resources/static/oauth2/sign-up.html | 1 + 7 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/leets/xcellentbe/global/auth/login/oauth/PasswordUtil.java create mode 100644 src/main/resources/static/index.html create mode 100644 src/main/resources/static/oauth2/sign-up.html diff --git a/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtAuthenticationFilter.java b/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtAuthenticationFilter.java index dc702ef..b474a43 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtAuthenticationFilter.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/jwt/JwtAuthenticationFilter.java @@ -140,7 +140,7 @@ public void checkAccessTokenAndAuthentication(HttpServletRequest request, HttpSe public void saveAuthentication(User myUser) { String password = myUser.getPassword(); // if (password == null) { // OAuth2 사용시 소셜로그인 비밀번호 생성 코드 - // password = PasswordUtil.generateRandomPassword(); + // password = PasswordUtils.generateRandomPassword(); // } UserDetails userDetailsUser = org.springframework.security.core.userdetails.User.builder() .username(myUser.getEmail()) diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java index 4fa6982..81982c9 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java @@ -15,6 +15,8 @@ public class OAuthAttributes { private String nameAttributeKey; private GoogleOAuthUserInfo googleOAuthUserInfo; + PasswordUtil passwordUtil = new PasswordUtil(); + @Builder private OAuthAttributes(String nameAttributeKey, GoogleOAuthUserInfo googleOAuthUserInfo) { this.nameAttributeKey = nameAttributeKey; @@ -31,7 +33,7 @@ public static OAuthAttributes of(String userNameAttributeName, Map tokenMap = new HashMap<>(); + + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new JavaTimeModule()); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + CustomOAuthUser oAuth2User = (CustomOAuthUser) authentication.getPrincipal(); Optional user = userRepository.findByEmail(oAuth2User.getEmail()); // User의 Role이 GUEST일 경우 처음 요청한 회원이므로 회원가입 페이지로 리다이렉트 if (oAuth2User.getRole() == Role.GUEST) { String accessToken = jwtService.createAccessToken(oAuth2User.getEmail()); + + tokenMap.put("accessToken", accessToken); + GlobalResponseDto> responseDto = GlobalResponseDto.success(tokenMap); + + response.setStatus(HttpServletResponse.SC_OK); + response.setContentType("application/json"); + response.setCharacterEncoding("UTF-8"); response.addHeader(jwtService.getAccessHeader(), "Bearer " + accessToken); - response.sendRedirect("/oauth2/sign-up"); // 프론트의 회원가입 추가 정보 입력 폼으로 ��다이렉트 + + String json = mapper.writeValueAsString(responseDto); + + response.getWriter().write(json); + // response.sendRedirect("/oauth2/sign-up.html"); + jwtService.sendAccessAndRefreshToken(response, accessToken, null); } else { loginSuccess(response, oAuth2User); // 로그인에 성공한 경우 access, refresh 토큰 생성 diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/PasswordUtil.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/PasswordUtil.java new file mode 100644 index 0000000..c693063 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/PasswordUtil.java @@ -0,0 +1,48 @@ +package com.leets.xcellentbe.global.auth.login.oauth; + +import java.security.SecureRandom; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +public class PasswordUtil { + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+"; + private static final int PASSWORD_LENGTH = 12; // 원하는 비밀번호 길이 + + private final BCryptPasswordEncoder passwordEncoder; + + public PasswordUtil() { + this.passwordEncoder = new BCryptPasswordEncoder(); + } + + // 랜덤 비밀번호 생성 및 해싱하여 반환 + public String generateHashedRandomPassword() { + String randomPassword = generateRandomPassword(); + return hashPassword(randomPassword); + } + + // 랜덤 비밀번호 생성 + private String generateRandomPassword() { + SecureRandom random = new SecureRandom(); + StringBuilder password = new StringBuilder(PASSWORD_LENGTH); + + for (int i = 0; i < PASSWORD_LENGTH; i++) { + int index = random.nextInt(CHARACTERS.length()); + password.append(CHARACTERS.charAt(index)); + } + + return password.toString(); + } + + // 비밀번호 해싱 + private String hashPassword(String password) { + return passwordEncoder.encode(password); + } + + public static void main(String[] args) { + PasswordUtil passwordUtil = new PasswordUtil(); + + // 랜덤 비밀번호 생성 및 해싱 + String hashedPassword = passwordUtil.generateHashedRandomPassword(); + System.out.println("해싱된 랜덤 비밀번호: " + hashedPassword); + } +} diff --git a/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java b/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java index 3410cb2..7e71f62 100644 --- a/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java +++ b/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java @@ -73,7 +73,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { authorize -> authorize .requestMatchers("/v3/api-docs", "/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**", - "/swagger/**", "/api/auth/register", "/api/auth/login").permitAll() + "/swagger/**", "/api/auth/register", "/api/auth/login", "/index.html").permitAll() .anyRequest().authenticated() ) .oauth2Login(oauth2 -> oauth2.successHandler(oAuthLoginSuccessHandler)); diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html new file mode 100644 index 0000000..9d9d664 --- /dev/null +++ b/src/main/resources/static/index.html @@ -0,0 +1 @@ +Google Login
diff --git a/src/main/resources/static/oauth2/sign-up.html b/src/main/resources/static/oauth2/sign-up.html new file mode 100644 index 0000000..aa9add1 --- /dev/null +++ b/src/main/resources/static/oauth2/sign-up.html @@ -0,0 +1 @@ +
테스트 페이지
From 7d5b2ad788333ff9a07da9224a5f9a4595d6e569 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Sun, 13 Oct 2024 00:56:07 +0900 Subject: [PATCH 04/19] =?UTF-8?q?feat:=20#9=20=EC=9D=B4=EB=A9=94=EC=9D=BC?= =?UTF-8?q?=20=EC=9D=B8=EC=A6=9D=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 추후 고도화 예정입니다 --- build.gradle | 4 + .../global/auth/login/AuthController.java | 17 ++++ .../global/auth/login/EmailCheckDto.java | 13 ++++ .../global/auth/login/EmailRequestDto.java | 8 ++ .../global/auth/login/EmailService.java | 77 +++++++++++++++++++ .../global/auth/login/RedisService.java | 31 ++++++++ .../global/auth/login/oauth/PasswordUtil.java | 3 +- .../xcellentbe/global/config/EmailConfig.java | 34 ++++++++ .../global/config/SecurityConfig.java | 2 +- 9 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/leets/xcellentbe/global/auth/login/EmailCheckDto.java create mode 100644 src/main/java/com/leets/xcellentbe/global/auth/login/EmailRequestDto.java create mode 100644 src/main/java/com/leets/xcellentbe/global/auth/login/EmailService.java create mode 100644 src/main/java/com/leets/xcellentbe/global/auth/login/RedisService.java create mode 100644 src/main/java/com/leets/xcellentbe/global/config/EmailConfig.java diff --git a/build.gradle b/build.gradle index c5a9fa8..e387028 100644 --- a/build.gradle +++ b/build.gradle @@ -57,6 +57,10 @@ dependencies { // OAuth2 implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + // SMTP, Redis + implementation 'org.springframework.boot:spring-boot-starter-mail' + implementation 'org.springframework.boot:spring-boot-starter-data-redis' + // Swagger implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java index 756b8d4..f965a5a 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java @@ -20,6 +20,7 @@ @RequiredArgsConstructor public class AuthController { private final UserService userService; + private final EmailService emailService; @PostMapping("/register") @Operation(summary = "회원가입", description = "회원가입을 합니다.") @@ -34,4 +35,20 @@ public String login(@RequestBody UserLoginRequestDto userLoginRequestDto) { // 로그인 로직 처리 return "로그인 성공"; } + + @PostMapping("/email/send") + public ResponseEntity> mailSend(@RequestBody EmailRequestDto emailRequestDto) { + return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success(emailService.joinEmail(emailRequestDto.getEmail()))); + } + + @PostMapping("/email/check") + public ResponseEntity> AuthCheck(@RequestBody EmailCheckDto emailCheckDto) { + Boolean Checked = emailService.checkAuthNum(emailCheckDto.getEmail(), emailCheckDto.getAuthNum()); + if (Checked) { + return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success("인증 성공")); + } else { + throw new NullPointerException("뭔가 잘못!"); + } + } } + diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/EmailCheckDto.java b/src/main/java/com/leets/xcellentbe/global/auth/login/EmailCheckDto.java new file mode 100644 index 0000000..64dd776 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/EmailCheckDto.java @@ -0,0 +1,13 @@ +package com.leets.xcellentbe.global.auth.login; + +import jakarta.validation.constraints.Email; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class EmailCheckDto { + @Email + private String email; + private String authNum; +} diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/EmailRequestDto.java b/src/main/java/com/leets/xcellentbe/global/auth/login/EmailRequestDto.java new file mode 100644 index 0000000..786fc67 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/EmailRequestDto.java @@ -0,0 +1,8 @@ +package com.leets.xcellentbe.global.auth.login; + +import lombok.Getter; + +@Getter +public class EmailRequestDto { + private String email; +} diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/EmailService.java b/src/main/java/com/leets/xcellentbe/global/auth/login/EmailService.java new file mode 100644 index 0000000..2160aa6 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/EmailService.java @@ -0,0 +1,77 @@ +package com.leets.xcellentbe.global.auth.login; +import org.springframework.stereotype.Service; +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import java.util.Random; +@Transactional +@RequiredArgsConstructor +@Service +@Slf4j +public class EmailService { + private final RedisService redisService; + private final JavaMailSender mailSender; + private int authNumber; + + //임의의 6자리 양수를 반환합니다. + public void makeRandomNumber() { + Random r = new Random(); + String randomNumber = ""; + for(int i = 0; i < 6; i++) { + randomNumber += Integer.toString(r.nextInt(10)); + } + + this.authNumber = Integer.parseInt(randomNumber); + } + + + //mail을 어디서 보내는지, 어디로 보내는지 , 인증 번호를 html 형식으로 어떻게 보내는지 작성합니다. + public String joinEmail(String email) { + makeRandomNumber(); + String setFrom = "dionisos198@naver.com"; // email-config에 설정한 자신의 이메일 주소를 입력 + String toMail = email; + String title = "회원 가입 인증 이메일 입니다."; // 이메일 제목 + String content = + "인증 번호는 " + authNumber + "입니다." + + "
" + + "인증번호를 제대로 입력해주세요"; //이메일 내용 삽입 + mailSend(setFrom, toMail, title, content); + return Integer.toString(authNumber); + } + + //이메일을 전송합니다. + public void mailSend(String setFrom, String toMail, String title, String content) { + MimeMessage message = mailSender.createMimeMessage();//JavaMailSender 객체를 사용하여 MimeMessage 객체를 생성 + try { + MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");//이메일 메시지와 관련된 설정을 수행합니다. + // true를 전달하여 multipart 형식의 메시지를 지원하고, "utf-8"을 전달하여 문자 인코딩을 설정 + helper.setFrom(setFrom);//이메일의 발신자 주소 설정 + helper.setTo(toMail);//이메일의 수신자 주소 설정 + helper.setSubject(title);//이메일의 제목을 설정 + helper.setText(content,true);//이메일의 내용 설정 두 번째 매개 변수에 true를 설정하여 html 설정으로한다. + mailSender.send(message); + } catch (MessagingException e) {//이메일 서버에 연결할 수 없거나, 잘못된 이메일 주소를 사용하거나, 인증 오류가 발생하는 등 오류 + // 이러한 경우 MessagingException이 발생 + e.printStackTrace();//e.printStackTrace()는 예외를 기본 오류 스트림에 출력하는 메서드 + } + redisService.setDataExpire(Integer.toString(authNumber),toMail,60*5L); + } + + public boolean checkAuthNum(String email,String authNum){ + System.out.println(authNum); + System.out.println(email); + if(redisService.getData(authNum)==null){ + return false; + } + else if(redisService.getData(authNum).equals(email)){ + return true; + } + else{ + return false; + } + } +} diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/RedisService.java b/src/main/java/com/leets/xcellentbe/global/auth/login/RedisService.java new file mode 100644 index 0000000..2b9789b --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/RedisService.java @@ -0,0 +1,31 @@ +package com.leets.xcellentbe.global.auth.login; + +import java.time.Duration; + +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.ValueOperations; +import org.springframework.data.redis.core.StringRedisTemplate; +@Service +@RequiredArgsConstructor +public class RedisService { + private final StringRedisTemplate redisTemplate;//Redis에 접근하기 위한 Spring의 Redis 템플릿 클래스 + + public String getData(String key){//지정된 키(key)에 해당하는 데이터를 Redis에서 가져오는 메서드 + ValueOperations valueOperations=redisTemplate.opsForValue(); + return valueOperations.get(key); + } + public void setData(String key,String value){//지정된 키(key)에 값을 저장하는 메서드 + ValueOperations valueOperations=redisTemplate.opsForValue(); + valueOperations.set(key,value); + } + public void setDataExpire(String key,String value,long duration){//지정된 키(key)에 값을 저장하고, 지정된 시간(duration) 후에 데이터가 만료되도록 설정하는 메서드 + ValueOperations valueOperations=redisTemplate.opsForValue(); + Duration expireDuration=Duration.ofSeconds(duration); + valueOperations.set(key,value,expireDuration); + } + public void deleteData(String key){//지정된 키(key)에 해당하는 데이터를 Redis에서 삭제하는 메서드 + redisTemplate.delete(key); + } +} diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/PasswordUtil.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/PasswordUtil.java index c693063..7c21841 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/PasswordUtil.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/PasswordUtil.java @@ -2,13 +2,14 @@ import java.security.SecureRandom; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; public class PasswordUtil { private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+"; private static final int PASSWORD_LENGTH = 12; // 원하는 비밀번호 길이 - private final BCryptPasswordEncoder passwordEncoder; + private final PasswordEncoder passwordEncoder; public PasswordUtil() { this.passwordEncoder = new BCryptPasswordEncoder(); diff --git a/src/main/java/com/leets/xcellentbe/global/config/EmailConfig.java b/src/main/java/com/leets/xcellentbe/global/config/EmailConfig.java new file mode 100644 index 0000000..e3b46ac --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/config/EmailConfig.java @@ -0,0 +1,34 @@ +package com.leets.xcellentbe.global.config; + +import java.util.Properties; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; + +@Configuration +public class EmailConfig { + @Bean + public JavaMailSender mailSender() {//JAVA MAILSENDER 인터페이스를 구현한 객체를 빈으로 등록하기 위함. + + JavaMailSenderImpl mailSender = new JavaMailSenderImpl();//JavaMailSender 의 구현체를 생성하고 + mailSender.setHost("smtp.gmail.com");// 속성을 넣기 시작합니다. 이메일 전송에 사용할 SMTP 서버 호스트를 설정 + mailSender.setPort(587);// 587로 포트를 지정 + mailSender.setUsername("ehs208@gachon.ac.kr");//구글계정을 넣습니다. + mailSender.setPassword("tght ngww bgah vqww");//구글 앱 비밀번호를 넣습니다. + + Properties javaMailProperties = new Properties();//JavaMail의 속성을 설정하기 위해 Properties 객체를 생성 + javaMailProperties.put("mail.transport.protocol", "smtp");//프로토콜로 smtp 사용 + javaMailProperties.put("mail.smtp.auth", "true");//smtp 서버에 인증이 필요 + javaMailProperties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");//SSL 소켓 팩토리 클래스 사용 + javaMailProperties.put("mail.smtp.starttls.enable", "true");//STARTTLS(TLS를 시작하는 명령)를 사용하여 암호화된 통신을 활성화 + javaMailProperties.put("mail.debug", "true");//디버깅 정보 출력 + javaMailProperties.put("mail.smtp.ssl.trust", "smtp.gmail.com");//smtp 서버의 ssl 인증서를 신뢰 + javaMailProperties.put("mail.smtp.ssl.protocols", "TLSv1.2");//사용할 ssl 프로토콜 버젼 + + mailSender.setJavaMailProperties(javaMailProperties);//mailSender에 우리가 만든 properties 넣고 + + return mailSender;//빈으로 등록한다. + } +} diff --git a/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java b/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java index 7e71f62..0074c62 100644 --- a/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java +++ b/src/main/java/com/leets/xcellentbe/global/config/SecurityConfig.java @@ -73,7 +73,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { authorize -> authorize .requestMatchers("/v3/api-docs", "/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**", - "/swagger/**", "/api/auth/register", "/api/auth/login", "/index.html").permitAll() + "/swagger/**", "/api/auth/register", "/api/auth/login", "/index.html", "/api/auth/**").permitAll() .anyRequest().authenticated() ) .oauth2Login(oauth2 -> oauth2.successHandler(oAuthLoginSuccessHandler)); From 04d0d3f624888ac6e452e39ad6bfe66c79eec175 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Sun, 13 Oct 2024 17:47:08 +0900 Subject: [PATCH 05/19] =?UTF-8?q?fix:=20#9=20=EC=9D=B4=EB=A9=94=EC=9D=BC?= =?UTF-8?q?=20=EC=9D=B8=EC=A6=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit key, value값 수정 --- .../global/auth/login/AuthController.java | 5 +++-- .../global/auth/login/EmailService.java | 17 ++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java index f965a5a..e220198 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java @@ -38,7 +38,8 @@ public String login(@RequestBody UserLoginRequestDto userLoginRequestDto) { @PostMapping("/email/send") public ResponseEntity> mailSend(@RequestBody EmailRequestDto emailRequestDto) { - return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success(emailService.joinEmail(emailRequestDto.getEmail()))); + emailService.joinEmail(emailRequestDto.getEmail()); + return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success()); } @PostMapping("/email/check") @@ -47,7 +48,7 @@ public ResponseEntity> AuthCheck(@RequestBody EmailChe if (Checked) { return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success("인증 성공")); } else { - throw new NullPointerException("뭔가 잘못!"); + throw new NullPointerException("유효하지 않은 인증번호입니다."); } } } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/EmailService.java b/src/main/java/com/leets/xcellentbe/global/auth/login/EmailService.java index 2160aa6..fd7f441 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/EmailService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/EmailService.java @@ -32,24 +32,27 @@ public void makeRandomNumber() { //mail을 어디서 보내는지, 어디로 보내는지 , 인증 번호를 html 형식으로 어떻게 보내는지 작성합니다. public String joinEmail(String email) { makeRandomNumber(); - String setFrom = "dionisos198@naver.com"; // email-config에 설정한 자신의 이메일 주소를 입력 String toMail = email; String title = "회원 가입 인증 이메일 입니다."; // 이메일 제목 String content = "인증 번호는 " + authNumber + "입니다." + "
" + "인증번호를 제대로 입력해주세요"; //이메일 내용 삽입 - mailSend(setFrom, toMail, title, content); + mailSend(toMail, title, content); return Integer.toString(authNumber); } //이메일을 전송합니다. - public void mailSend(String setFrom, String toMail, String title, String content) { + public void mailSend(String toMail, String title, String content) { + + if(redisService.getData(toMail)!=null){ + throw new IllegalArgumentException("이미 인증번호가 발송되었습니다."); + } + MimeMessage message = mailSender.createMimeMessage();//JavaMailSender 객체를 사용하여 MimeMessage 객체를 생성 try { MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");//이메일 메시지와 관련된 설정을 수행합니다. // true를 전달하여 multipart 형식의 메시지를 지원하고, "utf-8"을 전달하여 문자 인코딩을 설정 - helper.setFrom(setFrom);//이메일의 발신자 주소 설정 helper.setTo(toMail);//이메일의 수신자 주소 설정 helper.setSubject(title);//이메일의 제목을 설정 helper.setText(content,true);//이메일의 내용 설정 두 번째 매개 변수에 true를 설정하여 html 설정으로한다. @@ -58,16 +61,16 @@ public void mailSend(String setFrom, String toMail, String title, String content // 이러한 경우 MessagingException이 발생 e.printStackTrace();//e.printStackTrace()는 예외를 기본 오류 스트림에 출력하는 메서드 } - redisService.setDataExpire(Integer.toString(authNumber),toMail,60*5L); + redisService.setDataExpire(toMail,Integer.toString(authNumber),60*5L); } public boolean checkAuthNum(String email,String authNum){ System.out.println(authNum); System.out.println(email); - if(redisService.getData(authNum)==null){ + if(redisService.getData(email)==null){ return false; } - else if(redisService.getData(authNum).equals(email)){ + else if(redisService.getData(email).equals(authNum)){ return true; } else{ From 5a0017a5a07e025410c8f0c9088b1538a0f16312 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Sun, 13 Oct 2024 18:59:11 +0900 Subject: [PATCH 06/19] =?UTF-8?q?feat=20#9=20=EC=9D=B4=EB=A9=94=EC=9D=BC?= =?UTF-8?q?=20=EC=9D=B8=EC=A6=9D=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 예외처리를 포함하여 구현 완료 --- .../auth/email/AuthCodeAlreadySentException.java | 10 ++++++++++ .../global/auth/{login => email}/EmailCheckDto.java | 2 +- .../global/auth/{login => email}/EmailRequestDto.java | 2 +- .../global/auth/{login => email}/EmailService.java | 6 ++++-- .../global/auth/{login => email}/RedisService.java | 2 +- .../xcellentbe/global/auth/login/AuthController.java | 6 +++++- .../com/leets/xcellentbe/global/error/ErrorCode.java | 1 + .../global/error/exception/GlobalExceptionHandler.java | 9 +++++---- 8 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/leets/xcellentbe/global/auth/email/AuthCodeAlreadySentException.java rename src/main/java/com/leets/xcellentbe/global/auth/{login => email}/EmailCheckDto.java (81%) rename src/main/java/com/leets/xcellentbe/global/auth/{login => email}/EmailRequestDto.java (64%) rename src/main/java/com/leets/xcellentbe/global/auth/{login => email}/EmailService.java (95%) rename src/main/java/com/leets/xcellentbe/global/auth/{login => email}/RedisService.java (96%) diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/AuthCodeAlreadySentException.java b/src/main/java/com/leets/xcellentbe/global/auth/email/AuthCodeAlreadySentException.java new file mode 100644 index 0000000..c3cbc4d --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/AuthCodeAlreadySentException.java @@ -0,0 +1,10 @@ +package com.leets.xcellentbe.global.auth.email; + +import com.leets.xcellentbe.global.error.ErrorCode; +import com.leets.xcellentbe.global.error.exception.CommonException; + +public class AuthCodeAlreadySentException extends CommonException { + public AuthCodeAlreadySentException() { + super(ErrorCode.AUTH_CODE_ALREADY_SENT); + } +} diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/EmailCheckDto.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailCheckDto.java similarity index 81% rename from src/main/java/com/leets/xcellentbe/global/auth/login/EmailCheckDto.java rename to src/main/java/com/leets/xcellentbe/global/auth/email/EmailCheckDto.java index 64dd776..ecd5986 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/EmailCheckDto.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailCheckDto.java @@ -1,4 +1,4 @@ -package com.leets.xcellentbe.global.auth.login; +package com.leets.xcellentbe.global.auth.email; import jakarta.validation.constraints.Email; import lombok.Getter; diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/EmailRequestDto.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailRequestDto.java similarity index 64% rename from src/main/java/com/leets/xcellentbe/global/auth/login/EmailRequestDto.java rename to src/main/java/com/leets/xcellentbe/global/auth/email/EmailRequestDto.java index 786fc67..fcbb8ce 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/EmailRequestDto.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailRequestDto.java @@ -1,4 +1,4 @@ -package com.leets.xcellentbe.global.auth.login; +package com.leets.xcellentbe.global.auth.email; import lombok.Getter; diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/EmailService.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java similarity index 95% rename from src/main/java/com/leets/xcellentbe/global/auth/login/EmailService.java rename to src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java index fd7f441..d317d7e 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/EmailService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java @@ -1,4 +1,5 @@ -package com.leets.xcellentbe.global.auth.login; +package com.leets.xcellentbe.global.auth.email; + import org.springframework.stereotype.Service; import jakarta.mail.MessagingException; import jakarta.mail.internet.MimeMessage; @@ -8,6 +9,7 @@ import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import java.util.Random; + @Transactional @RequiredArgsConstructor @Service @@ -46,7 +48,7 @@ public String joinEmail(String email) { public void mailSend(String toMail, String title, String content) { if(redisService.getData(toMail)!=null){ - throw new IllegalArgumentException("이미 인증번호가 발송되었습니다."); + throw new AuthCodeAlreadySentException(); } MimeMessage message = mailSender.createMimeMessage();//JavaMailSender 객체를 사용하여 MimeMessage 객체를 생성 diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/RedisService.java b/src/main/java/com/leets/xcellentbe/global/auth/email/RedisService.java similarity index 96% rename from src/main/java/com/leets/xcellentbe/global/auth/login/RedisService.java rename to src/main/java/com/leets/xcellentbe/global/auth/email/RedisService.java index 2b9789b..ccacf90 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/RedisService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/RedisService.java @@ -1,4 +1,4 @@ -package com.leets.xcellentbe.global.auth.login; +package com.leets.xcellentbe.global.auth.email; import java.time.Duration; diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java index e220198..fe0c981 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java @@ -10,6 +10,10 @@ import com.leets.xcellentbe.domain.user.dto.UserLoginRequestDto; import com.leets.xcellentbe.domain.user.dto.UserSignUpRequestDto; import com.leets.xcellentbe.domain.user.service.UserService; +import com.leets.xcellentbe.global.auth.email.EmailCheckDto; +import com.leets.xcellentbe.global.auth.email.EmailRequestDto; +import com.leets.xcellentbe.global.auth.email.EmailService; +import com.leets.xcellentbe.global.error.exception.custom.InvalidInputValueException; import com.leets.xcellentbe.global.response.GlobalResponseDto; import io.swagger.v3.oas.annotations.Operation; @@ -48,7 +52,7 @@ public ResponseEntity> AuthCheck(@RequestBody EmailChe if (Checked) { return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success("인증 성공")); } else { - throw new NullPointerException("유효하지 않은 인증번호입니다."); + throw new InvalidInputValueException(); } } } diff --git a/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java b/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java index 4cb13a1..72e8b9b 100644 --- a/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java +++ b/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java @@ -17,6 +17,7 @@ public enum ErrorCode { ARTICLE_NOT_FOUND(404, "ARTICLE_NOT_FOUND", "게시물을 찾을 수 없습니다."), CHAT_ROOM_NOT_FOUND(404, "CHAT_ROOM_NOT_FOUND", "채팅방을 찾을 수 없습니다."), REJECT_DUPLICATION(409,"REJECT_DUPLICATION","중복된 값입니다."), + AUTH_CODE_ALREADY_SENT(429, "AUTH_CODE_ALREADY_SENT", "이미 인증번호를 전송했습니다."), INTERNAL_SERVER_ERROR(500, "INTERNAL_SERVER_ERROR", "서버 오류가 발생했습니다."); diff --git a/src/main/java/com/leets/xcellentbe/global/error/exception/GlobalExceptionHandler.java b/src/main/java/com/leets/xcellentbe/global/error/exception/GlobalExceptionHandler.java index 9c7ce36..bc2e940 100644 --- a/src/main/java/com/leets/xcellentbe/global/error/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/leets/xcellentbe/global/error/exception/GlobalExceptionHandler.java @@ -6,25 +6,26 @@ import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import com.leets.xcellentbe.global.error.*; +import com.leets.xcellentbe.global.response.GlobalResponseDto; @Slf4j @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(CommonException.class) // Custom Exception을 포괄적으로 처리 - public ResponseEntity handleCommonException(CommonException ex) { + public ResponseEntity> handleCommonException(CommonException ex) { ErrorCode errorCode = ex.getErrorCode(); // 전달된 예외에서 에러 코드 가져오기 ErrorResponse errorResponse = new ErrorResponse(errorCode); showErrorLog(errorCode); - return new ResponseEntity<>(errorResponse, HttpStatus.valueOf(errorCode.getStatus())); + return ResponseEntity.status(HttpStatus.valueOf(errorCode.getStatus())).body(GlobalResponseDto.fail(errorCode, errorResponse.getMessage())); } @ExceptionHandler(Exception.class) - public ResponseEntity handleGenericException(Exception ex) { + public ResponseEntity handleGenericException(Exception ex) { ErrorCode errorCode = ErrorCode.INTERNAL_SERVER_ERROR; ErrorResponse errorResponse = new ErrorResponse(errorCode); showErrorLog(errorCode); - return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); + return ResponseEntity.status(HttpStatus.valueOf(errorCode.getStatus())).body(GlobalResponseDto.fail(errorCode, errorResponse.getMessage())); } From 872b4d2fdaa08831978855743ebcd89aa455d6cb Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Sun, 13 Oct 2024 20:43:07 +0900 Subject: [PATCH 07/19] =?UTF-8?q?feat:=20#9=20=EB=8F=84=EC=BB=A4=20?= =?UTF-8?q?=EB=B9=8C=EB=93=9C=20=EB=82=B4=EC=9A=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ouath 및 mail관련 내용 추가 --- .gitignore | 1 + Dockerfile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 264074c..97d0405 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ application-dev.yaml application-local.yaml application-jwt.yaml application-oauth.yaml +application-mail.yaml ### macOS ### .DS_Store diff --git a/Dockerfile b/Dockerfile index 4b5b42a..7a0929f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,4 +9,4 @@ ARG JAR_FILE=build/libs/*.jar COPY ${JAR_FILE} app.jar # 운영 및 개발에서 사용되는 환경 설정을 분리 -ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=dev,jwt", "/app.jar"] +ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=dev,jwt,oauth,mail", "/app.jar"] From a627a8bbac8a9756effbccbf97522c7c143536b0 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Sun, 13 Oct 2024 21:20:26 +0900 Subject: [PATCH 08/19] =?UTF-8?q?#fix=20#9=20GitHub=20Actions=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/github-actions.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index a7fbe1c..1da65cc 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -86,6 +86,12 @@ jobs: port: 22 key: ${{ secrets.PRIVATE_KEY }} script: | + # 기존 컨테이너 중지 및 제거 + if [ "$(sudo docker ps -q -f name=xcellent-be)" ]; then + sudo docker stop xcellent-be + sudo docker rm xcellent-be + fi + sudo docker ps sudo docker pull ${{ secrets.DOCKER_USERNAME }}/xcellent-be sudo docker run -d -p 8080:8080 ${{ secrets.DOCKER_USERNAME }}/xcellent-be From 4c7f4f8e8aa91cc7b3f25b43760f45ce821c6972 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Sun, 13 Oct 2024 21:25:39 +0900 Subject: [PATCH 09/19] =?UTF-8?q?fix:=20#9=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EB=85=B8=EC=B6=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이메일 및 패스워드 노출을 제거 후 수정했습니다 --- .../leets/xcellentbe/global/config/EmailConfig.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/global/config/EmailConfig.java b/src/main/java/com/leets/xcellentbe/global/config/EmailConfig.java index e3b46ac..78de83b 100644 --- a/src/main/java/com/leets/xcellentbe/global/config/EmailConfig.java +++ b/src/main/java/com/leets/xcellentbe/global/config/EmailConfig.java @@ -2,6 +2,7 @@ import java.util.Properties; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mail.javamail.JavaMailSender; @@ -9,14 +10,21 @@ @Configuration public class EmailConfig { + + @Value("${mail.username}") + private String username; + + @Value("${jwt.mail.password}") + private String password; + @Bean public JavaMailSender mailSender() {//JAVA MAILSENDER 인터페이스를 구현한 객체를 빈으로 등록하기 위함. JavaMailSenderImpl mailSender = new JavaMailSenderImpl();//JavaMailSender 의 구현체를 생성하고 mailSender.setHost("smtp.gmail.com");// 속성을 넣기 시작합니다. 이메일 전송에 사용할 SMTP 서버 호스트를 설정 mailSender.setPort(587);// 587로 포트를 지정 - mailSender.setUsername("ehs208@gachon.ac.kr");//구글계정을 넣습니다. - mailSender.setPassword("tght ngww bgah vqww");//구글 앱 비밀번호를 넣습니다. + mailSender.setUsername(username);//구글계정을 넣습니다. + mailSender.setPassword(password);//구글 앱 비밀번호를 넣습니다. Properties javaMailProperties = new Properties();//JavaMail의 속성을 설정하기 위해 Properties 객체를 생성 javaMailProperties.put("mail.transport.protocol", "smtp");//프로토콜로 smtp 사용 From f600bbc364eeec7ad19f7f4c04ef23cdc8d8d9aa Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Sun, 13 Oct 2024 22:24:38 +0900 Subject: [PATCH 10/19] =?UTF-8?q?fix:=20#9=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/leets/xcellentbe/global/config/EmailConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/leets/xcellentbe/global/config/EmailConfig.java b/src/main/java/com/leets/xcellentbe/global/config/EmailConfig.java index 78de83b..67e8dce 100644 --- a/src/main/java/com/leets/xcellentbe/global/config/EmailConfig.java +++ b/src/main/java/com/leets/xcellentbe/global/config/EmailConfig.java @@ -14,7 +14,7 @@ public class EmailConfig { @Value("${mail.username}") private String username; - @Value("${jwt.mail.password}") + @Value("${mail.password}") private String password; @Bean From 366fc35bfe82a3cc8393f5812b518df76f744ae8 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Tue, 15 Oct 2024 11:33:24 +0900 Subject: [PATCH 11/19] =?UTF-8?q?fix:=20#9=20=EC=9D=98=EC=A1=B4=EC=84=B1?= =?UTF-8?q?=20=EC=A3=BC=EC=9E=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/auth/login/oauth/OAuthAttributes.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java index 81982c9..f96c2f9 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/OAuthAttributes.java @@ -12,15 +12,15 @@ @Getter public class OAuthAttributes { - private String nameAttributeKey; - private GoogleOAuthUserInfo googleOAuthUserInfo; - - PasswordUtil passwordUtil = new PasswordUtil(); + private final String nameAttributeKey; + private final GoogleOAuthUserInfo googleOAuthUserInfo; + private final PasswordUtil passwordUtil; @Builder - private OAuthAttributes(String nameAttributeKey, GoogleOAuthUserInfo googleOAuthUserInfo) { + private OAuthAttributes(String nameAttributeKey, GoogleOAuthUserInfo googleOAuthUserInfo, PasswordUtil passwordUtil) { this.nameAttributeKey = nameAttributeKey; this.googleOAuthUserInfo = googleOAuthUserInfo; + this.passwordUtil = passwordUtil; } public static OAuthAttributes of(String userNameAttributeName, Map attributes) { From 404b27d9c757fefbe225a395e18207ef869e2f0e Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Tue, 15 Oct 2024 11:38:19 +0900 Subject: [PATCH 12/19] =?UTF-8?q?refactor:=20#9=20=EC=96=BC=EB=A6=AC?= =?UTF-8?q?=EB=A6=AC=ED=84=B4=20=ED=98=95=EC=8B=9D=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/auth/email/EmailService.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java index d317d7e..0569254 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java @@ -66,17 +66,13 @@ public void mailSend(String toMail, String title, String content) { redisService.setDataExpire(toMail,Integer.toString(authNumber),60*5L); } - public boolean checkAuthNum(String email,String authNum){ - System.out.println(authNum); - System.out.println(email); - if(redisService.getData(email)==null){ - return false; - } - else if(redisService.getData(email).equals(authNum)){ - return true; - } - else{ + public boolean checkAuthNum(String email, String authNum) { + String storedAuthNum = redisService.getData(email); + + if (storedAuthNum == null) { return false; } + + return storedAuthNum.equals(authNum); } } From 29ed49db815257087f40d23f95651d845d648d41 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Tue, 15 Oct 2024 11:39:30 +0900 Subject: [PATCH 13/19] =?UTF-8?q?refactor=20#9:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/leets/xcellentbe/domain/user/domain/User.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java b/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java index e2b3169..89c7887 100644 --- a/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java +++ b/src/main/java/com/leets/xcellentbe/domain/user/domain/User.java @@ -55,8 +55,6 @@ public class User extends BaseTimeEntity { @Column(length = 50) private String email; - private String socialEmail; // 소셜 로그인 이메일 - @Column(length = 20) private String phoneNumber; From 462e8b7a2dc2fed9591c725fea79b8660b054262 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Tue, 15 Oct 2024 11:43:47 +0900 Subject: [PATCH 14/19] =?UTF-8?q?refactor=20:#9=20=EB=82=9C=EC=88=98=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leets/xcellentbe/global/auth/email/EmailService.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java index 0569254..a360874 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java @@ -22,12 +22,7 @@ public class EmailService { //임의의 6자리 양수를 반환합니다. public void makeRandomNumber() { Random r = new Random(); - String randomNumber = ""; - for(int i = 0; i < 6; i++) { - randomNumber += Integer.toString(r.nextInt(10)); - } - - this.authNumber = Integer.parseInt(randomNumber); + this.authNumber = 100000 + r.nextInt(900000); } From f4349fa6510285eef77b1344f97a0d919eba47de Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Tue, 15 Oct 2024 11:47:36 +0900 Subject: [PATCH 15/19] =?UTF-8?q?refactor:=20#9=20=EC=9D=B8=EC=A6=9D?= =?UTF-8?q?=EB=B2=88=ED=98=B8=20=EB=A7=8C=EB=A3=8C=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EC=83=81=EC=88=98=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leets/xcellentbe/global/auth/email/EmailService.java | 2 +- .../leets/xcellentbe/global/auth/email/RedisService.java | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java index a360874..d308d0f 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java @@ -58,7 +58,7 @@ public void mailSend(String toMail, String title, String content) { // 이러한 경우 MessagingException이 발생 e.printStackTrace();//e.printStackTrace()는 예외를 기본 오류 스트림에 출력하는 메서드 } - redisService.setDataExpire(toMail,Integer.toString(authNumber),60*5L); + redisService.setDataExpire(toMail,Integer.toString(authNumber)); } public boolean checkAuthNum(String email, String authNum) { diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/RedisService.java b/src/main/java/com/leets/xcellentbe/global/auth/email/RedisService.java index ccacf90..8be9cd5 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/email/RedisService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/RedisService.java @@ -10,6 +10,8 @@ @Service @RequiredArgsConstructor public class RedisService { + private static final long AUTH_CODE_EXPIRE_SECONDS = 300; + private final StringRedisTemplate redisTemplate;//Redis에 접근하기 위한 Spring의 Redis 템플릿 클래스 public String getData(String key){//지정된 키(key)에 해당하는 데이터를 Redis에서 가져오는 메서드 @@ -20,9 +22,9 @@ public void setData(String key,String value){//지정된 키(key)에 값을 저 ValueOperations valueOperations=redisTemplate.opsForValue(); valueOperations.set(key,value); } - public void setDataExpire(String key,String value,long duration){//지정된 키(key)에 값을 저장하고, 지정된 시간(duration) 후에 데이터가 만료되도록 설정하는 메서드 + public void setDataExpire(String key,String value){//지정된 키(key)에 값을 저장하고, 지정된 시간(duration) 후에 데이터가 만료되도록 설정하는 메서드 ValueOperations valueOperations=redisTemplate.opsForValue(); - Duration expireDuration=Duration.ofSeconds(duration); + Duration expireDuration=Duration.ofSeconds(AUTH_CODE_EXPIRE_SECONDS); valueOperations.set(key,value,expireDuration); } public void deleteData(String key){//지정된 키(key)에 해당하는 데이터를 Redis에서 삭제하는 메서드 From be965c452d8aa6305309266ad1b45076620b4a37 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Tue, 15 Oct 2024 18:43:19 +0900 Subject: [PATCH 16/19] =?UTF-8?q?refactor:=20#9=20=EC=9D=B8=EC=A6=9D=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xcellentbe/global/auth/email/EmailService.java | 14 ++++++++++---- .../global/auth/login/AuthController.java | 7 +------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java index d308d0f..a4e8790 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java @@ -10,6 +10,8 @@ import org.springframework.mail.javamail.MimeMessageHelper; import java.util.Random; +import com.leets.xcellentbe.global.error.exception.custom.InvalidInputValueException; + @Transactional @RequiredArgsConstructor @Service @@ -61,13 +63,17 @@ public void mailSend(String toMail, String title, String content) { redisService.setDataExpire(toMail,Integer.toString(authNumber)); } - public boolean checkAuthNum(String email, String authNum) { + public String checkAuthNum(String email, String authNum) { String storedAuthNum = redisService.getData(email); if (storedAuthNum == null) { - return false; + return "인증번호가 만료되었습니다."; + } + else if(!storedAuthNum.equals(authNum)){ + throw new InvalidInputValueException(); + } + else { + return "인증에 성공하였습니다."; } - - return storedAuthNum.equals(authNum); } } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java index fe0c981..bfdbbb4 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java @@ -48,12 +48,7 @@ public ResponseEntity> mailSend(@RequestBody EmailRequ @PostMapping("/email/check") public ResponseEntity> AuthCheck(@RequestBody EmailCheckDto emailCheckDto) { - Boolean Checked = emailService.checkAuthNum(emailCheckDto.getEmail(), emailCheckDto.getAuthNum()); - if (Checked) { - return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success("인증 성공")); - } else { - throw new InvalidInputValueException(); - } + return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success(emailService.checkAuthNum(emailCheckDto.getEmail(), emailCheckDto.getAuthNum()))); } } From fc54c6c68339660a8bbdac0d5e27b6d0aa0851ee Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Tue, 15 Oct 2024 18:57:33 +0900 Subject: [PATCH 17/19] =?UTF-8?q?refactor:=20#9=20=EC=9D=B4=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=20=EB=B0=9C=EC=86=A1=20=EA=B4=80=EB=A0=A8=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존의 try-catch문을 없애고, GlobalHandlerException이 처리하게 변경하였습니다. --- .../global/auth/email/EmailService.java | 21 +++++++------------ .../global/auth/login/AuthController.java | 4 +++- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java index a4e8790..6298675 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java @@ -29,7 +29,7 @@ public void makeRandomNumber() { //mail을 어디서 보내는지, 어디로 보내는지 , 인증 번호를 html 형식으로 어떻게 보내는지 작성합니다. - public String joinEmail(String email) { + public String joinEmail(String email) throws MessagingException { makeRandomNumber(); String toMail = email; String title = "회원 가입 인증 이메일 입니다."; // 이메일 제목 @@ -42,24 +42,19 @@ public String joinEmail(String email) { } //이메일을 전송합니다. - public void mailSend(String toMail, String title, String content) { + public void mailSend(String toMail, String title, String content) throws MessagingException { if(redisService.getData(toMail)!=null){ throw new AuthCodeAlreadySentException(); } MimeMessage message = mailSender.createMimeMessage();//JavaMailSender 객체를 사용하여 MimeMessage 객체를 생성 - try { - MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");//이메일 메시지와 관련된 설정을 수행합니다. - // true를 전달하여 multipart 형식의 메시지를 지원하고, "utf-8"을 전달하여 문자 인코딩을 설정 - helper.setTo(toMail);//이메일의 수신자 주소 설정 - helper.setSubject(title);//이메일의 제목을 설정 - helper.setText(content,true);//이메일의 내용 설정 두 번째 매개 변수에 true를 설정하여 html 설정으로한다. - mailSender.send(message); - } catch (MessagingException e) {//이메일 서버에 연결할 수 없거나, 잘못된 이메일 주소를 사용하거나, 인증 오류가 발생하는 등 오류 - // 이러한 경우 MessagingException이 발생 - e.printStackTrace();//e.printStackTrace()는 예외를 기본 오류 스트림에 출력하는 메서드 - } + MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");// true를 전달하여 multipart 형식의 메시지를 지원하고, "utf-8"을 전달하여 문자 인코딩을 설정 + helper.setTo(toMail);//이메일의 수신자 주소 설정 + helper.setSubject(title);//이메일의 제목을 설정 + helper.setText(content,true);//이메일의 내용 설정 두 번째 매개 변수에 true를 설정하여 html 설정으로한다. + mailSender.send(message); + redisService.setDataExpire(toMail,Integer.toString(authNumber)); } diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java index bfdbbb4..e569b16 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/AuthController.java @@ -17,6 +17,7 @@ import com.leets.xcellentbe.global.response.GlobalResponseDto; import io.swagger.v3.oas.annotations.Operation; +import jakarta.mail.MessagingException; import lombok.RequiredArgsConstructor; @RestController @@ -41,7 +42,8 @@ public String login(@RequestBody UserLoginRequestDto userLoginRequestDto) { } @PostMapping("/email/send") - public ResponseEntity> mailSend(@RequestBody EmailRequestDto emailRequestDto) { + public ResponseEntity> mailSend(@RequestBody EmailRequestDto emailRequestDto) throws + MessagingException { emailService.joinEmail(emailRequestDto.getEmail()); return ResponseEntity.status(HttpStatus.OK).body(GlobalResponseDto.success()); } From 1267609d5251808b483d37cb0a6c84f6c04ff1fd Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Tue, 15 Oct 2024 19:02:57 +0900 Subject: [PATCH 18/19] =?UTF-8?q?refactor:=20#9=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EB=A1=9C=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 안정성을 위해 null을 return 하지 않는 방식으로 변경하였습니다. --- .../global/auth/login/oauth/CustomOAuthUserService.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUserService.java b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUserService.java index 41f1f59..7c74a28 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUserService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/login/oauth/CustomOAuthUserService.java @@ -48,12 +48,8 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic } private User getUser(OAuthAttributes attributes) { - User findUser = userRepository.findByEmail(attributes.getGoogleOAuthUserInfo().getEmail()).orElse(null); - - if(findUser == null) { - return saveUser(attributes); - } - return findUser; + return userRepository.findByEmail(attributes.getGoogleOAuthUserInfo().getEmail()) + .orElseGet(() -> saveUser(attributes)); } private User saveUser(OAuthAttributes attributes) { From af9365da613af59d6b383178079fe3bf5aa05709 Mon Sep 17 00:00:00 2001 From: EunHyunsu Date: Tue, 15 Oct 2024 20:49:31 +0900 Subject: [PATCH 19/19] =?UTF-8?q?fix:=20#9=20=EC=9D=B4=EB=A9=94=EC=9D=BC?= =?UTF-8?q?=20=EC=A0=84=EC=86=A1=20=EA=B4=80=EB=A0=A8=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/auth/email/EmailCannotBeSent.java | 12 ++++++++++++ .../xcellentbe/global/auth/email/EmailService.java | 13 +++++++++---- .../leets/xcellentbe/global/error/ErrorCode.java | 3 ++- 3 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/leets/xcellentbe/global/auth/email/EmailCannotBeSent.java diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailCannotBeSent.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailCannotBeSent.java new file mode 100644 index 0000000..5cd6ce9 --- /dev/null +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailCannotBeSent.java @@ -0,0 +1,12 @@ +package com.leets.xcellentbe.global.auth.email; + +import com.leets.xcellentbe.global.error.ErrorCode; +import com.leets.xcellentbe.global.error.exception.CommonException; + +public class EmailCannotBeSent extends CommonException +{ + public EmailCannotBeSent() + { + super(ErrorCode.EMAIL_CANNOT_BE_SENT); + } +} diff --git a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java index 6298675..72aa5ec 100644 --- a/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java +++ b/src/main/java/com/leets/xcellentbe/global/auth/email/EmailService.java @@ -48,13 +48,18 @@ public void mailSend(String toMail, String title, String content) throws Messagi throw new AuthCodeAlreadySentException(); } + try { MimeMessage message = mailSender.createMimeMessage();//JavaMailSender 객체를 사용하여 MimeMessage 객체를 생성 - MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");// true를 전달하여 multipart 형식의 메시지를 지원하고, "utf-8"을 전달하여 문자 인코딩을 설정 - helper.setTo(toMail);//이메일의 수신자 주소 설정 + MimeMessageHelper helper = new MimeMessageHelper(message, true, + "utf-8");// true를 전달하여 multipart 형식의 메시지를 지원하고, "utf-8"을 전달하여 문자 인코딩을 설정 + helper.setTo("h");//이메일의 수신자 주소 설정 helper.setSubject(title);//이메일의 제목을 설정 - helper.setText(content,true);//이메일의 내용 설정 두 번째 매개 변수에 true를 설정하여 html 설정으로한다. + helper.setText(content, true);//이메일의 내용 설정 두 번째 매개 변수에 true를 설정하여 html 설정으로한다. mailSender.send(message); - + } + catch(Exception e) { + throw new EmailCannotBeSent(); + } redisService.setDataExpire(toMail,Integer.toString(authNumber)); } diff --git a/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java b/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java index 72e8b9b..b0d965f 100644 --- a/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java +++ b/src/main/java/com/leets/xcellentbe/global/error/ErrorCode.java @@ -18,7 +18,8 @@ public enum ErrorCode { CHAT_ROOM_NOT_FOUND(404, "CHAT_ROOM_NOT_FOUND", "채팅방을 찾을 수 없습니다."), REJECT_DUPLICATION(409,"REJECT_DUPLICATION","중복된 값입니다."), AUTH_CODE_ALREADY_SENT(429, "AUTH_CODE_ALREADY_SENT", "이미 인증번호를 전송했습니다."), - INTERNAL_SERVER_ERROR(500, "INTERNAL_SERVER_ERROR", "서버 오류가 발생했습니다."); + INTERNAL_SERVER_ERROR(500, "INTERNAL_SERVER_ERROR", "서버 오류가 발생했습니다."), + EMAIL_CANNOT_BE_SENT(500, "EMAIL_CANNOT_BE_SENT", "이메일 전송에 실패했습니다."); private final int status;