public JwtAuthenticationFilter(JwtUtil jwtUtil) {
this.jwtUtil = jwtUtil;
setFilterProcessesUrl("/api/login");
}ping
PONG
set venh-test data-valuel
OK
get venh-test
"data-valuel"spring.data.redis.host=localhost
spring.data.redis.port=6379public String joinEmail(String email) {
makeRandomNumber(); // 이메일 인증 코드 만들기
String toMail = email; // 누구에게 보낼지?
String title = "회원 가입 인증 이메일 입니다."; // 이메일 제목, postman : ?email=thddltkr10@naver.com
String content =
"<hybrid>를 방문해주셔서 감사합니다." + //html 형식으로 작성
"<br><br>" +
"인증 번호는 " + verificationCode + "입니다." +
"<br>" +
" "; //이메일 내용 삽입
sendEmail(toMail, title, content);
LocalDateTime expirationDateTime = LocalDateTime.now().plusMinutes(10);
// 만료시간 설정, now(): 지금으로부터, .plusMinures(10): 10분
EmailVerification emailVerification = new EmailVerification(email, verificationCode, expirationDateTime);
// EmailVerification는 new EmailVerification(userEmail, verificationCode, expirationDateTime); 으로 인스턴스화
emailVerificationRepository.save(emailVerification);
// 데이터베이스에 이메일 인증 정보를 저장
return Integer.toString(verificationCode);
}@Override
public String sendEmail(String toMail, String title, String content) {
MimeMessage message = emailSender.createMimeMessage();
// true 매개 값을 전달하면 multipart 형식의 메세지 전달이 가능.문자 인코딩 설정도 가능
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");
helper.setTo(toMail);
helper.setSubject(title);
// true 전달 > html 형식으로 전송 , 작성하지 않으면 단순 텍스트로 전달.
helper.setText(content, true);
mailSender.send(message);
} catch (MessagingException e) {
e.printStackTrace();
}
return redisUtil.setDataExpire(rcv, verificationCode, 60 * 5L);
}@PostMapping("/email")
public String sendEmail(@RequestParam String email) throws Exception {
String confirm = emailService.joinEmail(email);
return confirm;
}public void verificationCodePass(EmailVerificationRequestDto emailVerificationRequestDto) {
// 이메일 인증을 확인
if (!verificationCodeCheck(emailVerificationRequestDto)) {
throw new IllegalArgumentException("이메일 인증이 필요합니다.");
}
}
@Transactional // isApproved 값을 업데이트하고 있기 때문에 사용
// 이메일 인증 코드를 확인
public boolean verificationCodeCheck(EmailVerificationRequestDto emailVerificationRequestDto) {
String userEmail = emailVerificationRequestDto.getEmail();
int userEnteredVerificationCode = emailVerificationRequestDto.getVerificationCode();
EmailVerification verification = emailVerificationRepository.findByEmail(userEmail).orElseThrow(
() -> new IllegalArgumentException("인증 코드를 전송하고 메일을 확인해주세요.")
);
// 인증 코드를 보낸 메일이 있냐, 없냐 그 데이터를 찾는 것
if (verification.getVerificationCode() != userEnteredVerificationCode) {
// 저장된 인증 코드(verification.getVerificationCode())와 사용자가 입력한 인증 코드(userEnteredVerificationCode)를 비교하여 일치하지 않으면 throw
throw new IllegalArgumentException("올바른 인증 번호가 아닙니다.");
}
if (verification.getExpirationDateTime().isBefore(LocalDateTime.now())) {
// verification.getExpirationDateTime()를 사용하여 이메일 인증 정보의 인증 코드 유효 기간(expirationDateTime)을 가져오기
// 현재 시간(LocalDateTime.now())과 .isBefore를 사용하여 비교하고 throw
// (verification.getExpirationDateTime()이 LocalDateTime.now()보다 .isBefore(지났다면)?
throw new IllegalArgumentException("인증 시간이 만료되었습니다.");
}
verification.approve();
System.out.println(verification.isApproved());
// 올바른 인증 코드를 입력했을 경우 허가를 해줌 (=인증된 이메일이 됨)
return true;
}// 인증된 email 찾아서 확인
EmailVerification checkUserEmailApprove = emailVerificationRepository.findByEmail(email).orElseThrow(
() -> new IllegalArgumentException("Email을 인증해주세요.")
);
if (!checkUserEmailApprove.isApproved()) {
throw new IllegalArgumentException("인증되지 않은 Email입니다.");
} // throw new Exception -> 오류 반환 메세지@GetMapping("/email") //URL 대문자가 들어가면 안됩니다
public ResponseEntity<MsgResponseDto> emailCheck(@RequestBody EmailVerificationRequestDto emailVerificationRequestDto) {
userService.verificationCodePass(emailVerificationRequestDto);
return ResponseEntity.ok().body(new MsgResponseDto("이메일 인증 성공", HttpStatus.OK.value()));
}@PostMapping("/email-send")
public String sendEmail(@RequestParam String email) throws Exception {
String confirm = emailService.joinEmail(email);
return confirm;
}public static String makeRandomCode() {
// 난수의 범위 111111 ~ 999999 (6자리 난수)
Random r = new Random();
int checkNum = r.nextInt(888888) + 111111;
System.out.println("인증번호 : " + checkNum);
verificationCode = String.valueOf(checkNum); // checkNum이 authNumber에 담김
return r.toString();
}if (redisUtil.existData(email)) {
redisUtil.deleteData(email);
}String username = ((UserDetailsImpl) authResult.getPrincipal()).getUsername();
String username = ((UserDetailsImpl) authResult.getPrincipal()).getUsername();
ctrl + 클릭해서 들어가 보니 public class UserDetailsImpl implements UserDetails - public String getUsername()
@Override
public String getUsername() {
return user.getUserName();
}
빨간 줄이 떠 있어야 하는 public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter - protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) 의 String username = ((UserDetailsImpl) authResult.getPrincipal()).getUsername(); 의 getUsername(); 가 정상 작동?!
ctrl + 클릭해서 들어가 보니 public interface UserDetails extends Serializable
/**
* Returns the username used to authenticate the user. Cannot return
* <code>null</code>.
* @return the username (never <code>null</code>)
*/
String getUsername();
public class UserDetailsImpl implements UserDetails 에 빨간 줄이 떠 있고 public String UserNames()은 꺼져 있고 @Override에 빨간 줄, no usages!
public String UserNames()가 없어도
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter - protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) 의 String username = ((UserDetailsImpl) authResult.getPrincipal()).getUsername(); 의
getUsername(); 가 정상 작동되니까 그럼 필요 없는 거 아니야?
삭제하면 public class UserDetailsImpl implements UserDetails 에 빨간 줄
결론