본문 바로가기
Spring Boot (프로젝트)

[스프링 부트] 프로젝트 3 엔티티, 로그인 (비밀번호 암호화)

by Hoozy 2023. 3. 12.

이전 게시글 프로젝트 2 프론트엔드 구현

https://hoozy.tistory.com/entry/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-2-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B5%AC%ED%98%84

 

[스프링 부트] 프로젝트 2 프론트엔드 구현

이전 게시글 프로젝트 1 설정 https://hoozy.tistory.com/entry/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%84%A4%EC%A0%95-1 프로젝트 1 설정 (Spring Boot, MySQL) 이전 게시글 스프링 부트와 MySQL 연결 https://hoozy.tistory.com/entry/%E

hoozy.tistory.com

테이블과 매칭된 엔티티를 생성.

회원가입할 때 비밀번호를 암호화.

비밀번호 암호화

  • 비밀번호를 암호화하지 않고 DB에 저장하면, 해킹을 당했을 때 유저들의 정보가 그대로 유출될 수 있다.
  • 그래서 비밀번호 암호화를 해서 DB에 저장해야한다.

비밀번호 해싱

  • 단방향 해시 함수 : 알고리즘으로 의해 원본 데이터를 매핑시켜 완전히 다른 해시 데이터로 변환시키는 것.
  • 해시에 의해 암호화된 데이터를 다이제스트 라고 한다.
  • 해시 값인 다이제스트는 원본 데이터가 같으면 같은 값을 가진다.
  • 단독으로 해시 함수만 사용하면 '레인보우 테이블' 이라는 사람들이 많이 쓰는 비밀번호에 대해서 이미 해시 값을 모아놓은 테이블이다.
  • 이로인해 솔트 라는 무작위 값을 원본 데이터에 더한 후 해시 함수를 이용하는 방법을 사용해 해시 값을 통해 원본 데이터를 찾는데 어렵게 만든다.

솔트 방법

  • 여러 방법이 있지만, 저는 비밀번호 + 솔트 값 을 해시 함수인 SHA-256 함수를 사용해 해시 값을 DB에 저장하고 비교하는 방법.
  • 보통 한 번 보다는 여러번 반복해서 더욱 더 알기 어렵게 만든다.

프로젝트 비밀번호 암호화

  • 유저가 회원가입할 때 서비스에서 실행되는 메소드이다.
  • 처음에 유저만의 고유 솔트 값을 생성하고, 가입할 때 입력한 비밀번호와 솔트 값을 이용하여 해시 값을 구한다.
  • 이후 DB에 해싱된 비밀번호와 솔트 값을 넣는다.

  • SALT_SIZE는 16으로 설정했고, 솔트 값을 16바이트 크기로 생성한 후 16개의 랜덤 바이트 배열로 만들어 바이트 값으로 바꾼 후 반환해준다.

  • 해시 함수인 SHA-256 함수로 비밀번호와 솔트 값을 더한 값을 해싱해서 저장하는데, 이때 총 10번을 해싱해 보안성을 강화하고 바이트로 바꿔서 반환해준다.

  • 바이트 배열을 받아서 배열의 값마다 2자리 소문자인 16진수로 바꿔주는 메소드이다.

  • 로그인 할 때 비밀번호가 맞는지 체크하는 메소드.
  • 이메일에 맞는 솔트 값을 DB에서 가져와서 입력한 비밀번호와 솔트 값을 더한 값의 해싱 값이 DB에 있는 해싱한 비밀번호와 같은 값인지 확인 후 맞으면 로그인 시킨다.

엔티티

  • DB의 테이블과 같이 매핑하는 엔티티 생성.
  • 엔티티를 보기 전에 JPA는 무조건 ID 속성인 PK가 있어야 한다. 또한, ORACLE 은 SEQUENCE로 PK의 값 관리가 편하지만, MYSQL은 SEQUENCE를 지원하지 않으므로 IDENTITY 라는 타입을 써야한다. 자세한 건 아래 링크에 설명되어 있다.
    https://newwisdom.tistory.com/90
  • 저의 프로젝트는 편하게 하기 위해서 모두 AUTO를 설정하였습니다.

1. today

  • no 를 PK로 가지고, kno를 FK로 가지고 know의 정보를 담는다.

2. user

  • 이메일을 사이트 아이디로 쓰기 때문에 문자열이라서 AUTO_INCREMENT가 안된다. -> 따라서 @Id만 써야 한다.
  • 나머지는 테이블의 컬럼과 같기 때문에 @Column 어노테이션 없이 그대로 썼다.

3. know

  • 나머지는 다른게 없지만, likes에서 @ColumnDefault("0") 은 말 그대로 이 컬럽의 default 값이 0이라는 소리인데, JPA에서 save() 메소드를 실행할 때 만약 값이 없어서 insert를 하게되면 likes 컬럼의 default 값을 0으로 하는 것이다.

4. reply

  • kno는 know 테이블의 번호를 FK로 가지고, email은 user 테이블의 이메일을 FK로 가진다.
  • 생성일인 date는 mysql의 datetime과 호환하기 위해 TimeStamp로 한다.

5. chat

  • enum은 상수 집합으로 chat 엔티티에서는 채팅방에 들어올 때 JOIN, 채팅방에서 떠날 때 LEAVE, 채팅방 들어와서 채팅할 때 CHAT, 채팅방에 들어올 때 DB에서 불러오는 채팅 FIRST 를 설정했다.
  • @Transient 어노테이션은 DB에는 없지만 엔티티에서 사용해야 하는 필드일 때 쓴다. -> id 는 채팅 메시지의 채팅방 id를 가져올 때 쓰인다.
  • create 메소드는 채팅 인스턴스를 생성해서 채팅방, 작성자, 내용, 프로필, 타입을 넣어서 반환한다. -> 현재 시간을 포맷을 바꿔서 작성일로 넣는다.

6. room

  • chat과 유사하다.

7. addi

  • 현재 addi 테이블에서는 PK가 없어서 JPA에서 @Id 어노테이션이 없어서 인식을 못한다. 그래서 addiPK라는 가상 PK를 만들어 addi 엔티티를 만들어 사용하면 된다.

  • @EmbeddedId 는 복합 PK를 뜻하는 어노테이션으로 위에 실제 PK가 없는 addi 테이블의 컬럼 값을 넣고, 이 전체 컬럼을 복합 PK로 만들어 addi 엔티티를 만든다.
  • 여기서 addi의 컬럼을 호출할 때에는 addi.addi.no 이런식으로 호출해야 한다.

다음 게시글 프로젝트 4 백엔드 구현

https://hoozy.tistory.com/entry/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-4-%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B5%AC%ED%98%84

 

[스프링 부트] 프로젝트 4 백엔드 구현

다음 게시글 프로젝트 3 엔티티, 비밀번호 암호화 https://hoozy.tistory.com/entry/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-3-%EC%97%94%ED%8B%B0%ED%8B%B0-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-%EC%95%94%ED%98%B8%ED%99%9

hoozy.tistory.com

 

참고 자료

https://st-lab.tistory.com/100
https://newwisdom.tistory.com/90

댓글