Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAuth 로그인 기능 구현 #73

Merged
merged 22 commits into from
Apr 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
723183b
Feat: gitignore 파일에 oauth.properties 파일 추가
eNoLJ Apr 28, 2021
9927adf
Feat: user 스키마 생성
eNoLJ Apr 28, 2021
6f1741c
Feat: User, UserRepository 클래스 생성
eNoLJ Apr 28, 2021
5613928
Feat: UserController 생성
eNoLJ Apr 28, 2021
6bd1259
Feat: TokenResponseDTO 클래스 생성
eNoLJ Apr 28, 2021
b2af3cc
Merge branch 'be/feature/oauth' of https://github.com/skawnkk/sidedis…
eNoLJ Apr 29, 2021
a30999e
Merge branch 'dev-be' of https://github.com/skawnkk/sidedish into be/…
eNoLJ Apr 29, 2021
8e9697e
Merge branch 'dev-be' of https://github.com/skawnkk/sidedish into be/…
eNoLJ Apr 29, 2021
9931723
Merge branch 'dev-be' of https://github.com/skawnkk/sidedish into be/…
eNoLJ Apr 29, 2021
59debf3
Feat: UserService 클래스 생성
eNoLJ Apr 29, 2021
1e39cc5
Feat: User 클래스에 생성자와 update 메소드 생성
eNoLJ Apr 29, 2021
e9615a1
Feat: UserRepository 인터페이스에 findByUserId 생성
eNoLJ Apr 29, 2021
101c4a7
Feat: User 정보를 전달하는 DTO 생성
eNoLJ Apr 29, 2021
df1d29f
Feat: user 테이블의 id를 AUTO_INCREMENT 설정
eNoLJ Apr 29, 2021
914a8eb
Feat: User 클래스에 getter 메소드 생성
eNoLJ Apr 29, 2021
3ddcfc4
Feat: UserResponseDTO 클래스 생성
eNoLJ Apr 29, 2021
608993f
Feat: UserService 클래스의 메소드 수정
eNoLJ Apr 29, 2021
423ebf8
Feat: User 테이블 스키마 수정
eNoLJ Apr 29, 2021
131f40a
Feat: User 클래스에 기본 생성자 생성, removeToken 메소드 생성
eNoLJ Apr 29, 2021
e87c930
Feat: UserController 클래스에 logout 메소드 생성
eNoLJ Apr 29, 2021
4071738
Feat: UserService 클래스에 logout 메소드 생성
eNoLJ Apr 29, 2021
73b2daf
Feat: UserRepository 인터페이스에 findByEmail, findByToken 메소드 생성
eNoLJ Apr 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,5 @@ gradle-app.setting
.idea/workspace.xml
.idea/modules.xml
.idea/jarRepositories.xml

BE/src/main/resources/oauth.properties
67 changes: 67 additions & 0 deletions BE/src/main/java/com/mj_eno/sidedish/domain/user/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.mj_eno.sidedish.domain.user;

import com.mj_eno.sidedish.web.dto.EmailDTO;
import com.mj_eno.sidedish.web.dto.TokenDTO;
import com.mj_eno.sidedish.web.dto.UserInfoDTO;
import org.springframework.data.annotation.Id;

public class User {

@Id
private Long id;
private String name;
private String email;
private String userId;
private String token;

public User() {}

public User(UserInfoDTO userInfoDTO, EmailDTO emailDTO, TokenDTO tokenDTO) {
this.name = userInfoDTO.getName();
this.email = emailDTO.getEmail();
this.userId = userInfoDTO.getLogin();
this.token = tokenDTO.getAccess_token();
}

public void update(UserInfoDTO userInfoDTO, EmailDTO emailDTO, TokenDTO tokenDTO) {
this.name = userInfoDTO.getName();
this.email = emailDTO.getEmail();
this.userId = userInfoDTO.getLogin();
this.token = tokenDTO.getAccess_token();
}

public void removeToken() {
this.token = null;
}

public Long getId() {
return id;
}

public String getName() {
return name;
}

public String getEmail() {
return email;
}

public String getUserId() {
return userId;
}

public String getToken() {
return token;
}

@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", userId='" + userId + '\'' +
", token='" + token + '\'' +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.mj_eno.sidedish.domain.user;

import org.springframework.data.repository.CrudRepository;

import java.util.Optional;

public interface UserRepository extends CrudRepository<User, Long> {

Optional<User> findByEmail(String email);

Optional<User> findByToken(String token);
}
103 changes: 103 additions & 0 deletions BE/src/main/java/com/mj_eno/sidedish/service/UserService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.mj_eno.sidedish.service;

import com.mj_eno.sidedish.domain.user.User;
import com.mj_eno.sidedish.domain.user.UserRepository;
import com.mj_eno.sidedish.exception.EntityNotFoundException;
import com.mj_eno.sidedish.exception.ErrorMessage;
import com.mj_eno.sidedish.web.dto.EmailDTO;
import com.mj_eno.sidedish.web.dto.TokenDTO;
import com.mj_eno.sidedish.web.dto.UserInfoDTO;
import com.mj_eno.sidedish.web.dto.UserResponseDTO;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.env.Environment;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.List;

@PropertySource("classpath:/oauth.properties")
@Service
public class UserService {

private final UserRepository userRepository;
private final RestTemplate restTemplate;
private final Environment environment;

public UserService(UserRepository userRepository, Environment environment, RestTemplateBuilder restTemplateBuilder) {
this.userRepository = userRepository;
this.restTemplate = restTemplateBuilder.build();
this.environment = environment;
}

public UserResponseDTO login(String code) {
TokenDTO tokenDTO = tokenRequestApi(code);
UserInfoDTO userInfoDTO = userInfoRequestApi(tokenDTO.getAccess_token());
EmailDTO emailDTO = emailRequestApi(tokenDTO.getAccess_token());

if (verifyUser(emailDTO)) {
User user = findByEmail(emailDTO);
user.update(userInfoDTO, emailDTO, tokenDTO);
return new UserResponseDTO(userRepository.save(user));
}
User user = new User(userInfoDTO, emailDTO, tokenDTO);
return new UserResponseDTO(userRepository.save(user));
}

public void logout(String token) {
User user = findByToken(token);
user.removeToken();
userRepository.save(user);
}

private TokenDTO tokenRequestApi(String code) {
String id = environment.getProperty("github.client.id");
String secret = environment.getProperty("github.secret");
String url = environment.getProperty("github.access.token.url");
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("client_id", id)
.queryParam("client_secret", secret)
.queryParam("code", code);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
httpHeaders.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
HttpEntity<?> httpEntity = new HttpEntity<>(httpHeaders);
return restTemplate.exchange(builder.toUriString(), HttpMethod.POST, httpEntity, TokenDTO.class).getBody();
}

private UserInfoDTO userInfoRequestApi(String token) {
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("https://api.github.com/user");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set(HttpHeaders.AUTHORIZATION, "token " + token);
HttpEntity<?> httpEntity = new HttpEntity<>(httpHeaders);
return restTemplate.exchange(builder.toUriString(), HttpMethod.GET, httpEntity, UserInfoDTO.class).getBody();
}

private EmailDTO emailRequestApi(String token) {
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("https://api.github.com/user/emails");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set(HttpHeaders.AUTHORIZATION, "token " + token);
HttpEntity<?> httpEntity3 = new HttpEntity<>(httpHeaders);
List<EmailDTO> emailDTOList = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, httpEntity3, new ParameterizedTypeReference<List<EmailDTO>>() {}).getBody();
return emailDTOList.get(0);
}

private boolean verifyUser(EmailDTO emailDTO) {
return userRepository.findByEmail(emailDTO.getEmail()).isPresent();
}

private User findByEmail(EmailDTO emailDTO) {
return userRepository.findByEmail(emailDTO.getEmail()).orElseThrow(
() -> new EntityNotFoundException(ErrorMessage.ENTITY_NOT_FOUND)
);
}

private User findByToken(String token) {
return userRepository.findByToken(token).orElseThrow(
() -> new EntityNotFoundException(ErrorMessage.ENTITY_NOT_FOUND)
);
}
}
30 changes: 30 additions & 0 deletions BE/src/main/java/com/mj_eno/sidedish/web/UserController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.mj_eno.sidedish.web;

import com.mj_eno.sidedish.service.UserService;
import com.mj_eno.sidedish.web.dto.UserResponseDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

@RestController
public class UserController {

public final UserService userService;
private final Logger logger = LoggerFactory.getLogger(DishController.class);

public UserController(UserService userService) {
this.userService = userService;
}

@PostMapping("/login")
public UserResponseDTO login(@RequestParam String code) {
logger.info("로그인 요청");
return userService.login(code);
}

@GetMapping("/logout")
public void logout(@RequestHeader String token) {
logger.info("로그아웃 요청");
userService.logout(token);
}
}
21 changes: 21 additions & 0 deletions BE/src/main/java/com/mj_eno/sidedish/web/dto/EmailDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.mj_eno.sidedish.web.dto;

public class EmailDTO {

private String email;

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

@Override
public String toString() {
return "emailDTO{" +
"email='" + email + '\'' +
'}';
}
}
33 changes: 33 additions & 0 deletions BE/src/main/java/com/mj_eno/sidedish/web/dto/TokenDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.mj_eno.sidedish.web.dto;

public class TokenDTO {

private String access_token;
private String token_type;
private String scope;

public void setAccess_token(String access_token) {
this.access_token = access_token;
}

public void setToken_type(String token_type) {
this.token_type = token_type;
}

public void setScope(String scope) {
this.scope = scope;
}

public String getAccess_token() {
return access_token;
}

@Override
public String toString() {
return "TokenDTO{" +
"access_token='" + access_token + '\'' +
", token_type='" + token_type + '\'' +
", scope='" + scope + '\'' +
'}';
}
}
31 changes: 31 additions & 0 deletions BE/src/main/java/com/mj_eno/sidedish/web/dto/UserInfoDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.mj_eno.sidedish.web.dto;

public class UserInfoDTO {

private String login;
private String name;

public String getLogin() {
return login;
}

public void setLogin(String login) {
this.login = login;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "UserInfoDTO{" +
"login='" + login + '\'' +
", name='" + name + '\'' +
'}';
}
}
34 changes: 34 additions & 0 deletions BE/src/main/java/com/mj_eno/sidedish/web/dto/UserResponseDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.mj_eno.sidedish.web.dto;

import com.mj_eno.sidedish.domain.user.User;

public class UserResponseDTO {

private String name;
private String email;
private String userId;
private String token;

public UserResponseDTO(User user) {
this.name = user.getName();
this.email = user.getEmail();
this.userId = user.getUserId();
this.token = user.getToken();
}

public String getName() {
return name;
}

public String getEmail() {
return email;
}

public String getUserId() {
return userId;
}

public String getToken() {
return token;
}
}
13 changes: 13 additions & 0 deletions BE/src/main/resources/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,N
CREATE SCHEMA IF NOT EXISTS `side_dish` DEFAULT CHARACTER SET utf8;
USE `side_dish`;

-- -----------------------------------------------------
-- Table `side_dish`.`user`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `side_dish`.`user`;
CREATE TABLE IF NOT EXISTS `side_dish`.`user` (
`id` INT AUTO_INCREMENT,
`name` VARCHAR(45) NOT NULL,
`email` VARCHAR(45) NOT NULL,
`user_id` VARCHAR(45) NOT NULL,
`token` VARCHAR(255),
PRIMARY KEY (`id`))
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `side_dish`.`best_menu_category`
-- -----------------------------------------------------
Expand Down