기술 공부
패스워드 암호화
랼랼
2022. 4. 11. 22:02
Email security vector created by macrovector - www.freepik.com
1. UserService 에서
public UserEntity getByCredentials(
final String email, final String password, final PasswordEncoder encoder) {
final UserEntity originalUser=userRepository.findByEmail(email);
//matches 메서드 이용하여 salt를 고려하여 패스워드가 같은지 확인
if(originalUser!=null&&encoder.matches(password, originalUser.getPassword())) {
return originalUser;
}
return null;
}
email(고유 id)를 통해 UserEntity를 가져온 뒤,
encoder한 password와 현재 password가 서로 match 되는지를 확인한 뒤 UserEntity 객체를 리턴한다.
여기서 matches를 사용하는 이유는 인코더의 과정에 있다.
우리가 사용할 encoder는 BCrytPasswordEncoder를 사용할텐데
이를 사용하여 패스워드를 인코딩하게 되면, 인코딩 된 패스워드에 Salt라는 의미없고 랜덤한 문자들이 붙게된다.
따라서 같은 패스워드를 인코딩하게 되어도, Salt때문에 완전히 같지는 않다.
encoder의 matches는 이 Salt를 고려하여 두 값의 일치 여부를 판별해준다.
2. UserController에서
package com.example.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.dto.ResponseDTO;
import com.example.demo.dto.UserDTO;
import com.example.demo.model.UserEntity;
import com.example.demo.security.TokenProvider;
import com.example.demo.service.UserService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequestMapping("/auth")
public class UserController {
@Autowired
private UserService userService;
@Autowired
private TokenProvider tokenProvider;
//패스워드 암호와를 위한 엔코더
private PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
//회원 가입
@PostMapping("/signup")
public ResponseEntity<?> responseUser(@RequestBody UserDTO userDTO){
try {
//요청을 이용해 저장할 사용자 만들기
UserEntity user = UserEntity.builder()
.email(userDTO.getEmail())
.user(userDTO.getUser())
//비밀번호를 엔코더해서 저장
.password(passwordEncoder.encode(userDTO.getPassword()))
.build();
log.info(userDTO.getPassword());
//서비스를 이용해 리포지터리에 저장
UserEntity registeredUser = userService.create(user);
//유저정보 가져오기 (1개)
UserDTO responsedUser = UserDTO.builder()
.email(registeredUser.getEmail())
.id(registeredUser.getId())
.user(registeredUser.getUser())
.build();
//ok 리턴
return ResponseEntity.ok().body(responsedUser);
} catch (Exception e) {
//에러 시 에러 메세지 발생
ResponseDTO responseDTO = ResponseDTO.builder().error(e.getMessage()).build();
// log.warn("controller : "+e.getMessage());
return ResponseEntity.badRequest().body(responseDTO);
}
}
//로그인
@PostMapping("/signin")
public ResponseEntity<?> authenticate(@RequestBody UserDTO userDTO){
UserEntity user = userService.getByCredentials(
userDTO.getEmail(), userDTO.getPassword(),passwordEncoder);
if(user!=null) {
//토큰 생성
final String token = tokenProvider.create(user);
final UserDTO responseUserDTO = UserDTO.builder()
.email(user.getEmail())
.id(user.getId())
// .user(user.getUser())
.token(token)
.build();
return ResponseEntity.ok(responseUserDTO);
} else {
ResponseDTO responseDTO = ResponseDTO.builder()
.error("Login failed.")
.build();
return ResponseEntity.badRequest().body(responseDTO);
}
}
}
1) 비밀번호를 Entity에 build 시, 인코더를 이용하여 인코딩한 비밀번호를 저장한다.
2) 로그인 시 서비스에서 선언한 getByCredentials를 이용하여 해당 회원이 맞는지를 판별한다.
반응형