feat(user-service): Google Oauth 추가, github Oauth 삭제

- Google Oauth 추가
- Github Oauth 삭제
This commit is contained in:
hoon7566
2022-02-15 19:03:31 +09:00
parent 4b2e5865c4
commit 496711e47e
12 changed files with 149 additions and 56 deletions

View File

@@ -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>.*),/$\{segment}
- id: order-service
uri: lb://ORDER-SERVCIE
predicates:
- Path=/order-service/**
filters:
- RewritePath=/order-service/(?<segment>.*),/$\{segment}
- id: store-service
uri: lb://STORE-SERVCIE
predicates:
- Path=/store-service/**
filters:
- RewritePath=/store-service/(?<segment>.*),/$\{segment}
- id: user-service
uri: lb://USER-SERVICE
predicates:
- Path=/user-service/**
filters:
- RewritePath=/user-service/(?<segment>.*),/$\{segment}

View File

@@ -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'*/

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -8,4 +8,5 @@ public class NotExistUserException extends CustomException {
public NotExistUserException(String message) {
super(HttpStatus.CONFLICT, message);
}
}

View File

@@ -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<Customer, Long> {
Optional<Customer> findByEmail(String email);
}

View File

@@ -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<OAuth2UserRequest, OAuth2User> {
CustomerDto findCustomerByUserId(Long userId);
String authByGithub(String code);
}

View File

@@ -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<String> 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<OAuth2UserRequest,OAuth2User> 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();
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -1,4 +1,4 @@
server.port: 0
server.port: 60000
spring:
application: