Skip to content
This repository has been archived by the owner on Aug 13, 2022. It is now read-only.

회원가입 및 로그인 기능 추가 #3

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ dependencies {
testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation 'org.hamcrest:hamcrest-library:2.2'



/**
* (10/11) Intellij 내부적으로 JUnit을 지원해주고 있습니다.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intellij 지원이면 intellij가 아닌 환경에서는 에러가 나지 않나요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 내용은 개인적으로 블로그 글을 잘못 이해했습니다. 스프링 내부(org.springframework.boot:spring-boot-starter-test)에서 jupiter를 제공해주고 있으며, 따라서 추가했던 jupiter는 삭제했습니다.

* 따라서 아래 jupiter를 설정하면, version conflict로 인해 테스트코드가 정상적으로 동작하지 않을 수 있습니다.(MemberService Test 코드 작성 중 발견)
Expand All @@ -55,8 +57,6 @@ dependencies {
// JUnit5의 경우 api, engine을 함께 사용해야 한다.
// testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
// testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'

testRuntimeOnly 'com.h2database:h2'
}

test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

import java.time.LocalDateTime;
import me.naming.onlineshoppingmall.domain.ResponseData;
import org.springframework.http.HttpHeaders;
import me.naming.onlineshoppingmall.exception.MessageException;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
Expand All @@ -17,18 +16,22 @@
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

@ExceptionHandler(value = { RuntimeException.class })
protected ResponseEntity handleConflict(RuntimeException ex, WebRequest request) {
HttpHeaders httpHeaders = new HttpHeaders();

httpHeaders.setContentType(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE));
@ExceptionHandler(value = { MessageException.class })
protected ResponseEntity handleConflict(MessageException messageException, WebRequest request) {
String path = ((ServletWebRequest)request).getRequest().getRequestURI();
int code;

if(messageException.getStatusCode() != 0) {
code = messageException.getStatusCode();
} else {
code = HttpStatus.INTERNAL_SERVER_ERROR.value();
}

ResponseData responseData = ResponseData.builder()
.localDateTime(LocalDateTime.now())
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.statusCode(code)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게하면 status code가 body에 들어가지 않을까요?

.path(path)
.message(ex.getMessage())
.message(messageException.getMessage())
.build();

return new ResponseEntity<>(responseData, HttpStatus.INTERNAL_SERVER_ERROR);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
public class CommonConstant {
private CommonConstant() {};

public static final String LOGIN_INFO = "loginInfo";
}
5 changes: 2 additions & 3 deletions src/main/java/me/naming/onlineshoppingmall/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,15 @@ public class Member {

@Column(name = "EMAIL")
@NotNull
// @Pattern(regexp = "^[\\w!#$%&'*+/=?`{|}~^-]+(?:\\.[\\w!#$%&'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$")
@Email(message = "이메일 형식에 맞지 않습니다.")
private String email;

// 영문(소문자, 대문자), 숫자, 특수문자 조합 9~12자리 조합
@Column(name = "PASSWORD")
@NotNull
@Setter
// @Pattern(regexp = "^(?=.*\\d)(?=.*[~`!@#$%\\^&*()-])(?=.*[a-z])(?=.*[A-Z]).{9,12}$",
// message = "비밀번호는 영문 대,소문자와 숫자, 특수기호가 적어도 1개 이상씩 포함된 9자 ~ 12자의 비밀번호여야 합니다.")
@Pattern(regexp = "^(?=.*\\d)(?=.*[~`!@#$%\\^&*()-])(?=.*[a-z])(?=.*[A-Z]).{9,12}$",
message = "비밀번호는 영문 대,소문자와 숫자, 특수기호가 적어도 1개 이상씩 포함된 9자 ~ 12자의 비밀번호여야 합니다.")
private String password;

@Column(name = "NAME", length = 30)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
@Getter
public class ResponseData {
private LocalDateTime localDateTime;
private HttpStatus status;
private int statusCode;
private String path;
private String message;

public ResponseData(LocalDateTime localDateTime, HttpStatus status, String path, String message) {
public ResponseData(LocalDateTime localDateTime, int statusCode, String path, String message) {
this.localDateTime = localDateTime;
this.status = status;
this.statusCode = statusCode;
this.path = path;
this.message = message;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package me.naming.onlineshoppingmall.exception;

import org.springframework.http.HttpStatus;

public class MessageException extends RuntimeException{

private int statusCode;

public MessageException(String message) {
super(message);
this.statusCode = HttpStatus.INTERNAL_SERVER_ERROR.value();
}

public MessageException(String message, int statusCode) {
super(message);
this.statusCode = statusCode;
}

public int getStatusCode() {
return statusCode;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import java.security.GeneralSecurityException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
Expand Down Expand Up @@ -38,20 +33,10 @@ public String encrypt(String plainText) {
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(aesKey.substring(0, 16).getBytes()));
encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8.name()));

} catch (IllegalBlockSizeException e) {
logger.error("** IllegalBlockSizeException : {}", e);
} catch (BadPaddingException e) {
logger.error("** BadPaddingException : {}", e);
} catch (GeneralSecurityException e) {
logger.error("** GeneralSecurityException : {}", e);
} catch (UnsupportedEncodingException e) {
logger.error("** UnsupportedEncodingException : {}", e);
} catch (InvalidKeyException e) {
logger.error("** InvalidKeyException : {}", e);
} catch (InvalidAlgorithmParameterException e) {
logger.error("** InvalidAlgorithmParameterException : {}", e);
} catch (NoSuchAlgorithmException e) {
logger.error("** NoSuchAlgorithmException : {}", e);
} catch (NoSuchPaddingException e) {
logger.error("** NoSuchPaddingException : {}", e);
}
return new String(Base64.encodeBase64(encrypted));
}
Expand All @@ -68,20 +53,8 @@ public String decrypt(String encryptText) {
byte[] byteStr = Base64.decodeBase64(encryptText.getBytes());
aesDecode = new String(cipher.doFinal(byteStr), StandardCharsets.UTF_8.name());

} catch (UnsupportedEncodingException e) {
} catch (Exception e) {
logger.error("** Decode UnsupportedEncodingException : {}", e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그냥 아래의 내용들과 메세지만 약간씩 다른것같은데 한번에 처리할 수 있지 않을까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exception으로 모든 예외를 한꺼번에 처리해줄 수 있을 수 있지만, 예외 상황을 세부적으로 파악하기 위해 코드 내용을 작성해주는게 좋진 않을지 궁금합니다.

피드백 해주신 내용은 현재 GeneralSecurityExceptionUnsupportedEncodingException로 예외처리 했습니다.

} catch (IllegalBlockSizeException e) {
logger.error("** Decode IllegalBlockSizeException : {}", e);
} catch (BadPaddingException e) {
logger.error("** Decode BadPaddingException : {}", e);
} catch (InvalidKeyException e) {
logger.error("** Decode InvalidKeyException : {}", e);
} catch (InvalidAlgorithmParameterException e) {
logger.error("** Decode InvalidAlgorithmParameterException : {}", e);
} catch (NoSuchAlgorithmException e) {
logger.error("** Decode NoSuchAlgorithmException : {}", e);
} catch (NoSuchPaddingException e) {
logger.error("** Decode NoSuchPaddingException : {}", e);
}

if(StringUtils.isEmpty(aesDecode)) throw new RuntimeException("복호화 에러");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,33 @@
package me.naming.onlineshoppingmall.service;

import java.util.concurrent.RejectedExecutionException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import lombok.extern.log4j.Log4j2;
import me.naming.onlineshoppingmall.constant.CommonConstant;
import me.naming.onlineshoppingmall.domain.Member;
import me.naming.onlineshoppingmall.repository.MemberRepository;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Log4j2
@Service
public class MemberService {

private final MemberRepository memberRepository;
private final CryptoService shaService;
private final CryptoService aesService;

@Autowired
public MemberService(SHAServiceImpl shaService, AESServiceImpl aesService,
MemberRepository memberRepository) {
public MemberService(SHAServiceImpl shaService, AESServiceImpl aesService, MemberRepository memberRepository) {
this.shaService = shaService;
this.aesService = aesService;
this.memberRepository = memberRepository;
}

private final Logger logger = LogManager.getLogger(MemberService.class);

public void signUp(Member member) {

if (memberRepository.findByEmail(member.getEmail()) != null) {
throw new RuntimeException("이미 가입된 이메일 주소입니다.");
throw new RejectedExecutionException("이미 가입된 이메일 주소입니다.");
}
member.setMemberStatus(Member.MemberStatus.DEFAULT);

Expand All @@ -52,13 +49,12 @@ public void doLogin(String email, String password, HttpServletRequest request) {
Member member = memberRepository.findMemnoAndPasswordByEmail(email);
String encodePassword = shaService.encrypt(password);
if(member == null) {
throw new RuntimeException("존재하지 않는 이메일 주소 입니다.");
throw new NullPointerException("존재하지 않는 이메일 주소 입니다.");
}
if(!member.getPassword().equals(encodePassword)) {
throw new RuntimeException("비밀번호가 틀렸습니다");
throw new IllegalArgumentException("비밀번호가 틀렸습니다");
}

String encodeMemNo = aesService.encrypt(String.valueOf(member.getMemNo()));
httpSession.setAttribute("loginInfo", encodeMemNo);
httpSession.setAttribute(CommonConstant.LOGIN_INFO, member.getMemNo());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Log4j2
@Service
public class SHAServiceImpl implements CryptoService {

@Value("${encrypt.shaKey}")
private String shaKey;

private static final Logger logger = LogManager.getLogger(SHAServiceImpl.class);

@Override
public String encrypt(String plainText) {
String generatedPassword = null;
Expand All @@ -30,7 +28,7 @@ public String encrypt(String plainText) {
}
generatedPassword = sb.toString();
} catch (NoSuchAlgorithmException e) {
logger.error("** SHA512 NoSuchAlgorithmException : {}", e);
log.error("** SHA512 NoSuchAlgorithmException : {}", e);
}

if(StringUtils.isEmpty(generatedPassword)) {
Expand Down
Loading