νμκ°μ
μ΄λ©μΌ μΈμ¦μ κΈ°λ°μΌλ‘ νμκ°μ λ‘μ§μ μμ±νλ€. λ‘μ§μ λ€μκ³Ό κ°λ€.
1. μ¬μ©μκ° μ΄λ©μΌκ³Ό λΉλ°λ²νΈ λ± νμμ 보λ₯Ό μ λ ₯ν ν, νμκ°μ μμ²μ 보λΈλ€.
2. μλ²μμλ μ¬μ©μμ μ΄λ©μΌλ‘ μΈμ¦λ©μΌμ μ μ‘νκ³ , μ¬μ©μκ° μ λ ₯ν μ 보λ₯Ό Redisμ μμμ μ₯νλ€.
3. μ¬μ©μκ° μ μ‘λ λ©μΌμ λ§ν¬λ₯Ό ν΅ν΄ μΈμ¦νμΈ μμ²μ 보λΈλ€.
4. μλ²μμλ μΈμ¦νμΈ ν, Redisμ μ μ₯ λ νμ μ 보λ₯Ό DBμ μ μ₯νλ©° νμκ°μ μ λ§μΉλ€.
μ°¨μ₯λκ³Όμ μ½λ리뷰μμ ν΄λΉ λ‘μ§μ λν΄ μ‘°μΈμ λ°μλ€. μ΅κ·Όμλ νμκ°μ μ λ§μ³€μ§λ§ μμ§ μΈμ¦μ΄ μλ£λμ§ μμ μ¬μ©μμκ² μΌλ¨ μΌλΆμ κΆν(μ΅μνμ κΆν)λ§ μ 곡ν ν, μΈμ¦μ΄ μλ£λλ©΄ μΆκ° κΆνμ μ 곡νλ κ²μ΄ μΌλ°μ μ΄λΌλ κ²μ΄μλ€. νμ§λ§ νμ¬ κ°λ° μ€μΈ μλΉμ€(μμμ€λ·μ»΄ ν΄λ‘ νλ‘μ νΈ)μμλ λ‘κ·ΈμΈνμ§ μμ μ¬μ©μλ μ±μ©κ³΅κ³ λ₯Ό νμΈνλ λ±μ μΌλΆ κΈ°λ₯μ μ 곡νκΈ° λλ¬Έμ, μΌλ¨ λ‘μ§μ μμ νμ§λ μκΈ°λ‘ κ²°μ νλ€.
Redis μ€μ
μ¬μ©μκ° μΈμ¦μ μλ£νκΈ°κΉμ§ μμλ‘ μ¬μ©μ μ 보λ₯Ό μ μ₯ν μ μ₯μλ‘ Redisλ₯Ό μ¬μ©νλ€. λ€μμ λ΄κ° μμ±ν Redis μ€μ κ³Ό μ νΈμ΄λ€.
RedisConfig.java
@Configuration
public class RedisConfig {
@Bean
public RedisConnectionFactory redisConnectionFactory(){
LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory();
return lettuceConnectionFactory;
}
@Bean
public RedisTemplate<String,Object> redisTemplate(){
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
redisTemplate.setKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
}
RedisUtil.java
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void set(String key, Object o, int minutes) {
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(o.getClass()));
redisTemplate.opsForValue().set(key, o, minutes, TimeUnit.MINUTES);
}
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
public boolean delete(String key) {
return redisTemplate.delete(key);
}
public boolean hasKey(String key) { return redisTemplate.hasKey(key); }
}
μΈμ¦ λ©μΌ μ μ‘
UserController.java
μ¬μ©μκ° νμμ 보λ₯Ό μ
λ ₯ ν, νμκ°μ
μμ²/users/signup
μ 보λΈλ€. SignupRequestDto
μλ μ¬μ©μμ emailκ³Ό password λ±μ μ λ³΄κ° λ΄κ²¨μλ€.
@RequiredArgsConstructor
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
@PostMapping("/signup")
public ResponseEntity<ResultResponse> signup(@RequestBody SignupRequestDto signupRequestDto) {
userService.sendSignupMail(signupRequestDto);
return ResponseEntity.ok().body(
ResultResponse.builder()
.success(true)
.status(HttpStatus.OK.value())
.message("μΈμ¦ λ©μΌμ 보λμ΅λλ€.")
.build()
);
}
}
UserService.java
μ‘΄μ¬νλ μ΄λ©μΌμΈμ§ νμΈ ν, ν΄λΉ μ΄λ©μΌλ‘ random UUIDλ₯Ό key κ°μΌλ‘ κ°μ§λ λ§ν¬λ₯Ό μ μ‘νλ€. λ©μΌ μ μ‘μ΄ μ±κ³΅νλ©΄, ν΄λΉ UUIDλ₯Ό key κ°μΌλ‘ Redisμ μ¬μ©μ μ 보λ₯Ό 10λΆ λμ μμλ‘ μ μ₯νλ€.
@RequiredArgsConstructor
@Service
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final MailUtil mailUtil;
private final RedisUtil redisUtil;
public void sendSignupMail(SignupRequestDto signupRequestDto) {
String email = signupRequestDto.getEmail();
String passwd = passwordEncoder.encode(signupRequestDto.getPassword());
if(userRepository.countUser(email) > 0) throw new ExistEmailException(email);
String key = UUID.randomUUID().toString();
User user = User.builder()
.email(email)
.nickname("temp")
.passwd(passwd)
.role(1)
.build();
if(mailUtil.sendSignupMail(key, user)) redisUtil.set(key, user, 10);
}
}
MailUtil.java
λ©μΌμ ν¬ν¨ λ λ§ν¬λ μΈμ¦μ νμΈνλ μμ² λ§ν¬κ° κ±Έλ €μκ³ , key κ°μΌλ‘ UserServiceμμ μμ±ν UUIDλ₯Ό κ°μ§κ³ μλ€. ν΄λΉ keyλ Redisμ μ μ₯λ μ¬μ©μ μ 보μ key κ°μ΄κΈ°λ νλ€.
@Component
public class MailUtil {
@Value("${spring.mail.username}")
private String fromEmail;
@Value("${spring.mail.password}")
private String fromEmailpassword;
private Session session;
public MailUtil() {
Properties prop = new Properties();
prop.put("mail.smtp.host", "smtp.gmail.com");
prop.put("mail.smtp.port", 465);
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.trust", "smtp.gmail.com");
prop.put("mail.smtp.starttls.enable", "true");
this.session = Session.getDefaultInstance(prop, new javax.mail.Authenticator(){
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication(fromEmail, fromEmailpassword);
}
});
}
public boolean sendSignupMail(String key, User user){
try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(fromEmail));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail()));
message.setSubject("[ν©κ²©νμμ] μΈμ¦μ½λ μ μ‘");
message.setContent(
"<h1>[μ΄λ©μΌ μΈμ¦]</h1> <p>μλ λ§ν¬λ₯Ό ν΄λ¦νμλ©΄ μ΄λ©μΌ μΈμ¦μ΄ μλ£λ©λλ€.</p> " +
"<a href='http://localhost:8080/users/signup/confirm?key="+key+"' target='_blenk'>μ΄λ©μΌ μΈμ¦ νμΈ</a>"
,"text/html;charset=euc-kr"
);
Transport.send(message);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
}
μΈμ¦ νμΈ
μΈμ¦ λ©μΌμ λ§ν¬λ₯Ό ν΄λ¦νλ©΄, μλ²μ μΈμ¦ νμΈ μμ²μ 보λ΄κ² λκ³ μλ²λ νμκ°μ μ μ°¨λ₯Ό μλ£ν ν λ‘κ·ΈμΈνλ©΄μΌλ‘ 리λ€μ΄λ νΈ μν¨λ€.
UserController.java
@RequiredArgsConstructor
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
@GetMapping("/signup/confirm")
public void signupConfirm(@RequestParam("key")String key, HttpServletResponse response) throws IOException {
userService.registerUser(key);
response.sendRedirect("http://localhost:8080/");
}
}
UserService.java
@RequiredArgsConstructor
@Service
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final MailUtil mailUtil;
private final RedisUtil redisUtil;
public void registerUser(String key) {
User user = (User)redisUtil.get(key);
if(user==null) throw new TimeoutException();
String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
user.setCreatedAt(now);
user.setUpdatedAt(now);
user.setAccessedAt(now);
int userId = userRepository.registerUser(user);
if(userId > 0) redisUtil.delete(key);
String nickname = userRepository.getNickname(userId);
userRepository.updateNickname(userId, nickname, now);
}
}
'μ€λ§μΌκ²μ΄νΈ μλ²κ°λ°μΊ ν 4κΈ°' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[μλ²κ°λ°μΊ ν] μΈμ¦ μλ² - λ‘κ·ΈμΈ μ±λ₯ ν μ€νΈ : nGrinder (0) | 2020.02.15 |
---|---|
[μλ²κ°λ°μΊ ν] μΈμ¦ μλ² - AWS EC2 & RDS κ΅¬μΆ λ° λ°°ν¬ (0) | 2020.02.10 |
[μλ²κ°λ°μΊ ν] μΈμ¦ μλ² - λ‘κ·ΈμΈ : JWT + Redis (1) | 2020.02.10 |
[μλ²κ°λ°μΊ ν] μΈμ¦ μλ² - Spring Security + JWT (0) | 2020.02.02 |
π μλ²κ°λ°μΊ ν 4κΈ° (0) | 2020.01.12 |