Today I Learned
Spring Security 본문
Spring Security 는 입력 값을 SHA-256 알고리즘을 사용하는 해시 함수를 이용하여 암호화 시켜 준다.
- input 값을 넣으면 어떤 계산에 의해 output 을 반환하는 것이 해시 함수(Hash Function) 이다.
- 이때 output 은 해시(Hash) 이라고 한다.
- Hash 는 output 을 통해서 input 을 추론할 수 없다. 이것을 우리는 “비가역적” 이라고 한다.
- 객체화 하는 방식, 빈으로 등록하는 방식
- spring sequrity에서는 같은 평문을 넣어도 각기 다른 해쉬문을 반환한다(sault)
- 그래서 입력된 평문이 맞는지 확인하기 위해서는 제공되는 메서드를 사용 해야 한다.
단방향 암호화 sha-256
1234로 넣으면 이상한 글자로 알려줌
: 원문을 알 수 없음 : 비가역적
256바이트의 16진수로 표현 (성경을 넣어도 뭘넣어도 256바이트로 맞춘다 )
양방향 암호화
이상한 글자를 넣으면 다시 1234로 해줌
: 원문이 뭔지 볼 수 있음
비밀번호 암호하하기
1. db pw 컬럼 설정
member 테이블 만들 때 pw 타입을 varchar(200) 으로 하기 (암호화되면 커져서) 최소 100byte 로
한자를 넣든 몇글자를 넣든 똑같은 수로 맞추고 커짐
2. pom,xml에 라이브러리 추가
(라이브러리 추가를 하지 않으면, 객체화 안됨)
실제로 spring security 하려면 3개가 필요하지만
우리는 암호화만 할거라 하나만 가져옴
<!-- 암호화 관련 -->
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.2.17.RELEASE</version>
</dependency>
3. 코드 작성하기
- 1. 회원가입 시 비밀번호 암호화해서 db에 넣기
- 똑같은 pass여도 암호문이 달라짐 _ 똑같지 않은 이유 : 규칙성을 발견할 수 있기 때문에 (sault 방식으로 )
- 자체메서드가 있지만 신경쓸게 많음 라이브러리 쓰기
@RequestMapping(value = "/join.do")
public String join(Model model,@RequestParam HashMap<String, String> params) {
logger.info("params : " + params);
logger.info("평문 : " + params.get("pw"));
//암호화
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); //객체화 /빈으로 등록하는 방식도있음
//spring sequrity에서는 같은 평문을 넣어도 각기 다른 해쉬문을 반환한다(sault)
//그래서 입력된 평문이 맞는지 확인하기 위해서는 제공되는 메서드를 사용 해야 한다.
hashText = encoder.encode(params.get("pw"));
logger.info("암호 문 : " + hashText);
params.put("pw", hashText);
int row = service.join(params);
if(row>0) {
model.addAttribute("msg", "회원가입 완료됐습니다.");
}
return "login";
}
-2. 로그인시 이 암호화된 비번을 어떻게 비교하여 로그인을 하는 로직을 짤 것인가?
<내가 한 방법>
- 비밀번호를 찾아와서 hashText에 넣어주고 matches메서드를 사용해서 평문이랑 암호문을 비교함
- 그리고 그 값이 true일 경우, 로그인 단계를 서비스에 요청함
- 비밀번호를 찾는 쿼리와 로그인을 하는 쿼리 2개를 사용 - 비효율적
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
hashText = service.findPw(id);
logger.info(hashText);
boolean match = encoder.matches(pw, hashText); //평문이랑 암호문을 비교해줌 boolean 반환값
logger.info("일치 여부 : " + match);
String page="login";
if(match) {
int cnt = service.login(id,hashText);
if(cnt>0) {
session.setAttribute("loginId", id);
page="redirect:/list.do";
}
}else {
model.addAttribute("msg", "아이디 또는 비밀번호가 일치하지 않습니다.");
}
<강사님이 하신 코드>
사용자가 입력한 아이디를 가지고 비밀번호를 찾아와 hashPw변수에 넣어준다
사용자가 입력한 비밀번호와 이 hashPw가 일치하는지 matches 메서드를 사용해 비교해주고, true일 때 세션에 그 아이디를 저장
@RequestMapping(value = "/login.do")
public String confirm(HttpSession session,Model model,
@RequestParam String id, @RequestParam String pw) {
logger.info("평문 : " + pw);
//나는 서비스로 두개를 했는데 login 하나로 하면됨 쿼리를 바꿔줘서
String hashPw =service.login(id);
String page ="login";
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); //객체화
if(encoder.matches(pw, hashPw)) {
session.setAttribute("loginId",id);
page = "redirect:/list.do";
}else {
model.addAttribute("msg", "아이디 또는 비밀번호가 일치하지 않습니다.");
}
return page;
}
'Spring Framework' 카테고리의 다른 글
Build (0) | 2022.07.18 |
---|---|
Spring _ Scheduler (0) | 2022.07.14 |
패키지가 여러개일 경우 설정 방법, AOP (0) | 2022.07.14 |
Properties 설정 (0) | 2022.07.11 |
커넥션 풀 설정 (0) | 2022.07.11 |