From 496711e47e3d7a69aae158fa24516823d20cf133 Mon Sep 17 00:00:00 2001 From: hoon7566 Date: Tue, 15 Feb 2022 19:03:31 +0900 Subject: [PATCH] =?UTF-8?q?feat(user-service):=20Google=20Oauth=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20github=20Oauth=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Google Oauth 추가 - Github Oauth 삭제 --- .../src/main/resources/application.yml | 28 ++++++ user-service/build.gradle | 1 + .../domain/user/dto/CustomerDto.java | 5 + .../domain/user/entity/Customer.java | 10 +- .../userservice/domain/user/entity/User.java | 10 +- .../user/exception/NotExistUserException.java | 1 + .../user/repository/CustomerRepository.java | 5 + .../domain/user/service/UserService.java | 7 +- .../domain/user/service/UserServiceImpl.java | 95 +++++++++++++------ .../domain/user/web/UserController.java | 21 +--- .../global/security/WebSecurity.java | 20 +++- .../src/main/resources/application.yml | 2 +- 12 files changed, 149 insertions(+), 56 deletions(-) diff --git a/customer-apigateway-service/src/main/resources/application.yml b/customer-apigateway-service/src/main/resources/application.yml index 7211d74..58d0ba0 100644 --- a/customer-apigateway-service/src/main/resources/application.yml +++ b/customer-apigateway-service/src/main/resources/application.yml @@ -12,3 +12,31 @@ eureka: spring: application: name: customer-apigateway-service + + cloud: + gateway: + routes: + - id: owner-frontend-service + uri: lb://CUSTOMER-FRONTEND-SERVICE + predicates: + - Path=/customer-frontend-service/** + filters: + - RewritePath=/owner-frontend-service/(?.*),/$\{segment} + - id: order-service + uri: lb://ORDER-SERVCIE + predicates: + - Path=/order-service/** + filters: + - RewritePath=/order-service/(?.*),/$\{segment} + - id: store-service + uri: lb://STORE-SERVCIE + predicates: + - Path=/store-service/** + filters: + - RewritePath=/store-service/(?.*),/$\{segment} + - id: user-service + uri: lb://USER-SERVICE + predicates: + - Path=/user-service/** + filters: + - RewritePath=/user-service/(?.*),/$\{segment} \ No newline at end of file diff --git a/user-service/build.gradle b/user-service/build.gradle index c9b53b4..aaa9f2e 100644 --- a/user-service/build.gradle +++ b/user-service/build.gradle @@ -35,6 +35,7 @@ dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' /*implementation 'org.springframework.boot:spring-boot-starter-amqp'*/ implementation 'org.springframework.boot:spring-boot-starter-security' + compileOnly 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.cloud:spring-cloud-starter-config' /*implementation 'org.springframework.kafka:spring-kafka'*/ diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/CustomerDto.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/CustomerDto.java index ac60aa5..649ea9d 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/CustomerDto.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/CustomerDto.java @@ -1,5 +1,6 @@ package com.justpickup.userservice.domain.user.dto; +import com.justpickup.userservice.domain.user.entity.AuthType; import com.justpickup.userservice.domain.user.entity.Customer; import lombok.Builder; import lombok.Getter; @@ -7,12 +8,16 @@ import lombok.Getter; @Getter public class CustomerDto extends UserDto { + private AuthType authType; + public CustomerDto(Customer customer) { super(customer); + this.authType = customer.getOauthType(); } @Builder public CustomerDto(Long id, String password, String name, String phoneNumber) { super(id, password, name, phoneNumber); } + } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/entity/Customer.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/entity/Customer.java index 1dacbee..679db16 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/entity/Customer.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/entity/Customer.java @@ -5,12 +5,20 @@ import lombok.Getter; import lombok.NoArgsConstructor; import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; import javax.persistence.Table; @Entity @Table(name = "customer") @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Customer extends User { + @Enumerated(EnumType.STRING) private AuthType oauthType; - private String oauthId; + + + public Customer(String email, String password, String name, String phoneNumber, AuthType oauthType) { + super(email, password, name, phoneNumber,Role.USER); + this.oauthType = oauthType; + } } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/entity/User.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/entity/User.java index 645dc6a..ad7694d 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/entity/User.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/entity/User.java @@ -18,18 +18,26 @@ public abstract class User extends BaseEntity { @Column(name = "user_id") private Long id; + private String email; + private String password; private String name; private String phoneNumber; + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private Role role; + @Column(insertable = false,updatable = false) private String dtype; - public User(String password, String name, String phoneNumber) { + public User(String email, String password, String name, String phoneNumber, Role role) { + this.email = email; this.password = password; this.name = name; this.phoneNumber = phoneNumber; + this.role = role; } } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/exception/NotExistUserException.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/exception/NotExistUserException.java index 51da51c..701cdb8 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/exception/NotExistUserException.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/exception/NotExistUserException.java @@ -8,4 +8,5 @@ public class NotExistUserException extends CustomException { public NotExistUserException(String message) { super(HttpStatus.CONFLICT, message); } + } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/repository/CustomerRepository.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/repository/CustomerRepository.java index 1ade0b8..40ebbb8 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/repository/CustomerRepository.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/repository/CustomerRepository.java @@ -1,7 +1,12 @@ package com.justpickup.userservice.domain.user.repository; +import com.justpickup.userservice.domain.user.entity.AuthType; import com.justpickup.userservice.domain.user.entity.Customer; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface CustomerRepository extends JpaRepository { + + Optional findByEmail(String email); } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserService.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserService.java index d02ea20..5b57799 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserService.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserService.java @@ -1,9 +1,12 @@ package com.justpickup.userservice.domain.user.service; import com.justpickup.userservice.domain.user.dto.CustomerDto; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; +import org.springframework.security.oauth2.core.user.OAuth2User; -public interface UserService { +public interface UserService extends OAuth2UserService { CustomerDto findCustomerByUserId(Long userId); - String authByGithub(String code); } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java index b4ce052..1875c8a 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java @@ -5,21 +5,36 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.justpickup.userservice.domain.user.dto.CustomerDto; +import com.justpickup.userservice.domain.user.dto.OAuthAttributeDto; +import com.justpickup.userservice.domain.user.entity.AuthType; import com.justpickup.userservice.domain.user.entity.Customer; import com.justpickup.userservice.domain.user.exception.NotExistUserException; import com.justpickup.userservice.domain.user.repository.CustomerRepository; import lombok.*; import lombok.extern.slf4j.Slf4j; import org.springframework.core.env.Environment; +import org.springframework.data.annotation.ReadOnlyProperty; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; +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.DefaultOAuth2User; +import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.client.RestTemplate; +import javax.servlet.http.HttpSession; +import java.io.Serializable; +import java.util.Collections; import java.util.HashMap; +import java.util.Optional; +import java.util.function.Function; @Service @RequiredArgsConstructor @@ -28,6 +43,7 @@ import java.util.HashMap; public class UserServiceImpl implements UserService { private final CustomerRepository customerRepository; + private final HttpSession httpSession; private final Environment env; @Override @@ -38,37 +54,6 @@ public class UserServiceImpl implements UserService { return new CustomerDto(customer); } - @Override - public String authByGithub(String code) { - RestTemplate restTemplate = new RestTemplate(); - AuthRequest authRequest = new AuthRequest(); - authRequest.setCode(code); - authRequest.setClient_id(env.getProperty("oauth.github.client-id")); - authRequest.setClient_secret(env.getProperty("oauth.github.client-password")); - String accessToken = restTemplate.postForObject("https://github.com/login/oauth/access_token", authRequest, String.class); - - accessToken = accessToken.substring(accessToken.indexOf("access_token=")+13); - accessToken = accessToken.substring(0,accessToken.indexOf("&")); - - log.info("accessToken::" +accessToken); - HttpHeaders headers = new HttpHeaders(); - headers.set("Authorization", "Bearer "+accessToken); - HttpEntity request = new HttpEntity(headers); - ResponseEntity response = restTemplate.exchange("https://api.github.com/user", HttpMethod.GET, request, String.class); - AuthResponse authResponse=null; - try { - authResponse = new ObjectMapper().readValue(response.getBody(), AuthResponse.class); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } - log.info(authResponse.getName()); - - - log.info("access_token::" + accessToken); - return authResponse.getName(); - } - - @Data @NoArgsConstructor @AllArgsConstructor @@ -89,4 +74,52 @@ public class UserServiceImpl implements UserService { private String client_secret; } + + + + @Override + @Transactional(readOnly = false) + public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { + OAuth2UserService delegate = new DefaultOAuth2UserService(); + OAuth2User oAuth2User = delegate.loadUser(userRequest); + //OAuth 서비스 id + String registrationId = userRequest.getClientRegistration().getRegistrationId(); + //OAuth 로그인 진행시 키가 되는 필드값 + String userNameAttributeName = userRequest.getClientRegistration() + .getProviderDetails() + .getUserInfoEndpoint() + .getUserNameAttributeName(); + + // OAuth2UserService + OAuthAttributeDto attributeDto = OAuthAttributeDto.of(registrationId, userNameAttributeName,oAuth2User.getAttributes()); + + Customer customer = customerRepository.save( + customerRepository.findByEmail(attributeDto.getEmail()) + .orElse(attributeDto.toEntity(attributeDto)) + ); + + httpSession.setAttribute("user", new SessionCustomer(customer)); // SessionUser (직렬화된 dto 클래스 사용) + + return new DefaultOAuth2User( + Collections.singleton(new SimpleGrantedAuthority(customer.getRole().getKey())) + , attributeDto.getAttributes() + , attributeDto.getNameAttributeKey()); + + } + + @Getter + public class SessionCustomer implements Serializable { + private String name; + private String email; + + public SessionCustomer(Customer user){ + this.name = user.getName(); + this.email = user.getEmail(); + } + } + + + + + } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java index dceae79..bd7b6a9 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java @@ -1,6 +1,7 @@ package com.justpickup.userservice.domain.user.web; import com.justpickup.userservice.domain.user.dto.CustomerDto; +import com.justpickup.userservice.domain.user.entity.Customer; import com.justpickup.userservice.domain.user.service.UserService; import com.justpickup.userservice.global.dto.Result; import lombok.*; @@ -17,6 +18,7 @@ import org.springframework.web.client.RestTemplate; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import java.util.Objects; +import java.util.Optional; @RestController @RequiredArgsConstructor @@ -49,25 +51,6 @@ public class UserController { } } - @GetMapping("/afterLogin") - public ResponseEntity afterLogin(@RequestParam String code){ - log.info("로그인 성공 - code::"+ code); - - String accessToken = userService.authByGithub(code); - - - - - // access token 발급받는다 -> User DB에 저장한다. github ID 를 db에 저장한다. - // Oauth type, id 저장 . password - // - // https://api.github.com/user - // 이미 있는 github iD? 회원 가입한 사용자. - // - - - return ResponseEntity.ok(accessToken); - } } diff --git a/user-service/src/main/java/com/justpickup/userservice/global/security/WebSecurity.java b/user-service/src/main/java/com/justpickup/userservice/global/security/WebSecurity.java index 1aecf96..4ff3b05 100644 --- a/user-service/src/main/java/com/justpickup/userservice/global/security/WebSecurity.java +++ b/user-service/src/main/java/com/justpickup/userservice/global/security/WebSecurity.java @@ -1,5 +1,7 @@ package com.justpickup.userservice.global.security; +import com.justpickup.userservice.domain.user.service.UserService; +import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -7,11 +9,27 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur @Configuration @EnableWebSecurity +@RequiredArgsConstructor public class WebSecurity extends WebSecurityConfigurerAdapter { + private final UserService userService; + @Override protected void configure(HttpSecurity http) throws Exception { - http.authorizeHttpRequests().antMatchers("/**").permitAll(); + http.csrf().disable() + .authorizeRequests() + .antMatchers("/login").permitAll() + .and() + .logout() + .logoutSuccessUrl("/") + .and() + .oauth2Login() + .userInfoEndpoint() + .userService(userService); + + super.configure(http); + + } } diff --git a/user-service/src/main/resources/application.yml b/user-service/src/main/resources/application.yml index eb4b35d..b30ea22 100644 --- a/user-service/src/main/resources/application.yml +++ b/user-service/src/main/resources/application.yml @@ -1,4 +1,4 @@ -server.port: 0 +server.port: 60000 spring: application: