[Practice] 메일 전송 (1)

2021. 4. 20. 00:49Spring/Practice

1. 문제

  • 회원가입 시 가입된 회원에게 가입메일을 전송하는 API

 

 

 

2. 풀이

- application.yml

spring:

  ...
  
  ### 메일
  mail:
    username: ozofweird@gmail.com
    password: [메일 비밀번호]
    host: smtp.gmail.com
    port: 587
    properties: 
      mail:
        smtp:
          auth: true
          starttls: 
            enable: true

- build.gradle

implementation group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '2.4.5'

- MailComponent.java

package com.example.jpa.sample.util;

import lombok.experimental.UtilityClass;
import org.springframework.security.crypto.bcrypt.BCrypt;

@UtilityClass
public class PasswordUtils {

    public static Boolean equalPassword(String password, String encryptedPassword) {
        return BCrypt.checkpw(password, encryptedPassword);
    }

    public static String encryptPassword(String password) {
        return BCrypt.hashpw(password, BCrypt.gensalt());
    }
}

- PasswordUtils.java

package com.example.jpa.sample.util;

import lombok.experimental.UtilityClass;
import org.springframework.security.crypto.bcrypt.BCrypt;

@UtilityClass
public class PasswordUtils {

    public static Boolean equalPassword(String password, String encryptedPassword) {
        return BCrypt.checkpw(password, encryptedPassword);
    }

    public static String encryptPassword(String password) {
        return BCrypt.hashpw(password, BCrypt.gensalt());
    }
}

- WebMvcConfig.java (특정 API가 인터셉터에 의해 인증을 요구하지 않도록 설정)

package com.example.jpa.sample.config;

import com.example.jpa.sample.common.interceptor.CommonInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(new CommonInterceptor())
                .addPathPatterns("/api/*")
                .excludePathPatterns("/api/public/*");
    }
}

- UserService.java

package com.example.jpa.sample.user.service;

import com.example.jpa.sample.board.model.ServiceResult;
import com.example.jpa.sample.user.entity.User;
import com.example.jpa.sample.user.model.*;

import java.util.List;

public interface UserService {

    ...

    ServiceResult addUser(UserInput userInput);
}

- UserServiceImpl.java

package com.example.jpa.sample.user.service;

import com.example.jpa.sample.board.model.ServiceResult;
import com.example.jpa.sample.common.MailComponent;
import com.example.jpa.sample.common.exception.BizException;
import com.example.jpa.sample.user.entity.User;
import com.example.jpa.sample.user.entity.UserInterest;
import com.example.jpa.sample.user.model.*;
import com.example.jpa.sample.user.repository.UserCustomRepository;
import com.example.jpa.sample.user.repository.UserInterestRepository;
import com.example.jpa.sample.user.repository.UserRepository;
import com.example.jpa.sample.util.PasswordUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@RequiredArgsConstructor
@Service
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;
    private final UserCustomRepository userCustomRepository;
    private final UserInterestRepository userInterestRepository;

    private final MailComponent mailComponent;

    ...
    
    @Override
    public ServiceResult addUser(UserInput userInput) {
        Optional<User> optionalUser = userRepository.findByEmail(userInput.getEmail());
        if(!optionalUser.isPresent()) {
            throw new BizException("이미 가입된 이메일입니다.");
        }

        String encryptPassword = PasswordUtils.encryptPassword(userInput.getPassword());

        User user = User.builder()
                .email(userInput.getEmail())
                .name(userInput.getName())
                .regDate(LocalDateTime.now())
                .password(encryptPassword)
                .phone(userInput.getPhone())
                .status(UserStatus.Using)
                .build();

        userRepository.save(user);

        // 메일 전송
        String fromEmail = "ozofweird@gmail.com";
        String fromName = "관리자";
        String toEmail = user.getEmail();
        String toName = user.getName();
        String title = "회원가입을 축하드립니다.";
        String contents = "회원가입을 축하드립니다.";

        mailComponent.send(fromEmail, fromName, toEmail, toName, title, contents);

        return ServiceResult.success();
    }
}

- ApiUserController.java

package com.example.jpa.sample.user.controller;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.example.jpa.sample.board.entity.Board;
import com.example.jpa.sample.board.entity.BoardComment;
import com.example.jpa.sample.board.model.ServiceResult;
import com.example.jpa.sample.board.service.BoardService;
import com.example.jpa.sample.common.model.ResponseResult;
import com.example.jpa.sample.notice.entity.Notice;
import com.example.jpa.sample.notice.entity.NoticeLike;
import com.example.jpa.sample.notice.model.NoticeResponse;
import com.example.jpa.sample.notice.model.ResponseError;
import com.example.jpa.sample.notice.repository.NoticeLikeRepository;
import com.example.jpa.sample.notice.repository.NoticeRepository;
import com.example.jpa.sample.user.entity.User;
import com.example.jpa.sample.user.exception.ExistsEmailException;
import com.example.jpa.sample.user.exception.PasswordNotMatchException;
import com.example.jpa.sample.user.exception.UserNotFoundException;
import com.example.jpa.sample.user.model.*;
import com.example.jpa.sample.user.repository.UserPointRepository;
import com.example.jpa.sample.user.repository.UserRepository;
import com.example.jpa.sample.user.service.UserPointService;
import com.example.jpa.sample.user.service.UserService;
import com.example.jpa.sample.util.JwtUtils;
import com.example.jpa.sample.util.PasswordUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@RequiredArgsConstructor
@RestController
public class ApiUserController {

    ...

    // 문제 1
    @PostMapping("/api/public/user") // public url에 대해서는 인터셉터가 거치지 않음
    public ResponseEntity<?> addUser(@RequestBody UserInput userInput) {
        ServiceResult result = userService.addUser(userInput);
        return ResponseResult.success(result);
    }

}
728x90

'Spring > Practice' 카테고리의 다른 글

[Practice] 메일 전송 (3)  (0) 2021.04.20
[Practice] 메일 전송 (2)  (0) 2021.04.20
[Practice] Open API 연동 시 API 프로퍼티 활용  (0) 2021.04.20
[Practice] 인터셉터 활용 (2)  (0) 2021.04.20