본문 바로가기
Project/소경관

[소경관] : @Entity를 @Setter없이 View에서 Controller로 값을 받아와 @Builder를 통해 DB에 넣기

by 오주현 2022. 4. 12.
반응형

Entity를 Setter없이 View에서 Controller로 값 받아와 @Builder를 통해DB에 넣기

  • 며칠 헤매다 드디어 성공했다.
    • 내가 너무 어렵게 생각하고 있었다.
  • View에서 값을 받아 Controller에 넘겨주고 Controller에서 View에서 받아 온 값을 Entity에 담아 Service에 넘긴다. Service는 받은 값을 JpaRepository를 상속 받은 interface UserRepository에 저장한다.
  • @Builder를 사용해 View에서 값을 받아 DB에 저장하기
    • 매개 변수가 더 있지만 몇 가지로 간추려 작성해 본다.
    @PostMapping("/user/regUser/insert")
        public String InsertRegUser(HttpServletRequest request) throws Exception{
    
            log.info(this.getClass().getName() + ".InsertRegUser 회원가입 로직 처리 시작 !!");
    
            UserEntity userEntity = UserEntity.builder()
                    .userName(request.getParameter("userName"))
                    .userPn(request.getParameter("userPn"))
                    .userEmail(request.getParameter("userEmail"))
                    .userId(request.getParameter("userId"))
                    .userPw(request.getParameter("userPw"))
                    .userAddr(request.getParameter("userAddr"))
                    .build();
    
            log.info("UserEntity ={}", userEntity);
    
            userService.createUser(userEntity);
    
            return "/user/logIn";
        }
    
    • Controller에서 View에서 받아온 값을 UserEntity에 HttpServletRequest를 통해 담아주고 Service로 보내준다.
    public interface IUserService {
    
        int createUser(UserEntity userEntity) throws Exception;
    }
    
    • 나중에 회원 가입 여부 체크를 위해 int형으로 interface를 만들었다.
    @Override
    public int createUser(UserEntity userEntity) throws Exception {
    
        iUserRepository.save(userEntity);
        
        return 0;
    }
    
    • Controller에서 담은 UserEntity를 저장한다.
    public interface IUserRepository extends JpaRepository<UserEntity, Long> {}
       
    
    • 인터페이스만 만들어도 알아서 구현체를 생성해 준다.
    • 값이 정상적으로 들어온다.
  • 암호화 알고리즘도 추가해서 적용했다.
package project.SPM.util;

import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;

public class EncryptUtil {
    /**
     *
     * 암호화 알고리즘에 추가시킬 암호화 문구
     *
     * 일반적인 암호화 알고리즘 SHA-256를 통해서만 암호화 시킬 경우, 암호화 된 값만 보고 일반적인 비밀번호에 대한 값을 쉽게
     * 예측이 가능함 따라서, 암호화 할때 암호화되는 값에 추가적인 문자열을 붙여서 함계 암호화를 진행함
     *
     */

    final static String addMessage = "PolyDataAnalysis";
    /**
     * AES128-CBC 암호화 알고리즘에 사용되는 초기 백터와 암호화 키
     */

    /**
     *    해시 알고리즘 (단방향 암호화 알고리즘) -SHA-256
     *
     * @param 암호화 시킬 값
     * @return 암호화된 값
     *
     * */
    final static byte[] ivBytes = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};
    /**
     * AES128-CBC 암호화 알고리즘에 사용되는 초기 백터와 암호화키
     */
    final static String key = "PolyTechnic12345";
    public static String encHashSHA256(String str) throws Exception{
        String res = "";
        String plantText = addMessage + str;
        try {
            //자바는 기본적으로 표준 암호화 알고리즘을 java.security패키지를 통해 제공함
            //여러 해시 알고리즘 중 가장 많이 사용되는 SHA-256를 지원하고 있음
            MessageDigest sh = MessageDigest.getInstance("SHA-256");
            sh.update(plantText.getBytes());
            byte byteData[] = sh.digest();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < byteData.length; i++) {
                sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
            }
            res = sb.toString();
            //자바에서 제공하는 알고리즘이 아닌 경유, 에러 발생
        }catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            res = "";
        }
        return res;
    }
    /**
     * AES128 CBC 암호화 함수
     *
     * 128은 암호화 키 길이를 의미함 128비트는 = 16바이트(1바이트=8비트 * 16 = 128)
     */
    public static String encAES128CBC(String str)
            throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
        byte[] textBytes = str.getBytes("UTF-8");
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        SecretKeySpec newKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
        Cipher cipher = null;
        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
        return Base64.encodeBase64String(cipher.doFinal(textBytes));
    }
    /**
     * AES128 CBC 암호화 함수
     *
     * 128은 암호화 키 길이를 의미함 128비트는 = 16바이트(1바이트=8비트 * 16 = 128)
     */
    public static String decAES128CBC(String str)
            throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
        byte[] textBytes = Base64.decodeBase64(str);
        //byte[] textBytes = str.getBytes("UTF-8");
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        SecretKeySpec newKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
        return new String(cipher.doFinal(textBytes), "UTF-8");
    }
}
  • 암호화 알고리즘을 따로 Util에 정의한다.
UserEntity userEntity = UserEntity.builder()
                .userEmail(EncryptUtil.encAES128CBC(request.getParameter("userEmail")))
                .userPw(EncryptUtil.encHashSHA256(request.getParameter("userPw")))
                .build();
  • 비밀번호는 해시 양방향, 이메일은 단방향으로 암호화를 적용해 주었다.
반응형

댓글