1. /authenticate 분석
JwtAuthenticationController 에서 body에서 받은 email과 password를
authenticateByEmailAndPassword로 보내서 인증절차를 거친다
(email값이 없을때 UsernameNotFoundException 발생시키고,
password가 일치하지 않으면 password not matched 발생시킨다)
인증절차를 거친 member를 jwtTokenUtil에 보내서 토큰을 발급받는다
발급받으면 ResponseEntity로 응답(토큰 리턴)을 나타낸다
2. /authenticate - Sequnence Diagram
2.1 START
- URL에 /authenticate를 실어서 authenticate을 요청한다
- JwtRequest body에는 e-mail, password가 들어간다
2.2 JwtAuthenticationController
@PostMapping("/authenticate")
public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtRequest authenticationRequest) throws Exception {
final Member member = userDetailsService
.authenticateByEmailAndPassword(authenticationRequest.getEmail(),
authenticationRequest.getPassword());
final String token = jwtTokenUtil.generateToken(member.getEmail());
return ResponseEntity.ok(new JwtResponse(token));
}
createAuthenticationToken(JwtRequest request)
- 요청으로 들어온 email과 password의 값이 들어있다
final Member member = userDetailsService
.authenticateByEmailAndPassword(authenticationRequest.getEmail(),
authenticationRequest.getPassword())
- userDetailService의 authenticateByEmailAndPassword()에 요청받은 email,password 값을 넣어 메소드를 호출해서 return 값을 member에 담는다
final String token = jwtTokenUtil.generateToken(member.getEmail());
- jwtTokenUtil의 generateToken() 에 위에서 얻은 member 값을 넣어 return 값을 token에 담는다
2.2.1 JwtUserDtailService
public Member authenticateByEmailAndPassword(String email, String password){
Member member = memberRepository.findByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException(email));
if(!passwordEncoder.matches(password, member.getPassword())){
throw new BadCredentialsException("Password not matched");
}
return member;
}
Member member = memberRepository.findByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException(email));
- memberRepository.findByEmail()에 email 값을 넣어 멤버가 있는지 확인?
>없다면 UserNameNotFoundException 에러 발생(요청 끝냄)
>있다면 다음 if문을 통해 비밀번호 검사
if(!passwordEncoder.matches(password, member.getPassword())){
throw new BadCredentialsException("Password not matched");
}
- passwordEncoder.maches()를 이용해 요청받은 password 값과 member의 password 값을 비교(패스워드는 암호화되어있다)
> 일치하지않으면 BadCredentialsException 에러 발생
2.2.1.1 MemberRepository
public interface MemberRepository extends CrudRepository<Member, Long> {
Optional<Member> findByEmail(String email);
}
- 요청 받은 Email을 넣어서 값이 있는지 확인
2.2.2 JwtTokenUtil
public String generateToken(String id) {
return generateToken(id, new HashMap<>());
}
public String generateToken(String id, Map<String, Object> claims) {
return doGenerateToken(id, claims);
}
private String doGenerateToken(String id, Map<String, Object> claims) {
return Jwts.builder()
.setClaims(claims)
.setId(id)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000))
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
- Controller에서 받은 email 값을 generateToken(String id)에서 받은 email과 새로 생성한 HashMap을 ->
아래의 generateToken(String id, Map(String, object) claims) 받은 email과 새로 생성한 claims를 ->
아래의 doGenerateToken()로 보낸다.
doGenerateToken() : Jwts 로 토큰 생성
- claims : HashMap (key와 value를 가짐)
- claims에 token의 id set
- claims에 token 생성시각 기록
- claims에 token 유효시간 기록 (생성시각 + JWT_TOKEN_VALIDITY)
(public static final long JWT_TOKEN_VALIDITY = 5 * 60 * 60; : 즉 5시간 유효시간)
- claims에 token 암호화 알고리즘 선택(…하면서 salt로 쓸 secret key 설정)
compact()는 String return 값을 Jwts에 담는다
참조 사이트
Sup2's blog-Spring Security + JWT로 Token기반 Security Login 구현하기 (sup2is.github.io)
Sup2's blog-Spring Security + JWT로 Token기반 Security Login 구현하기
sup2is.github.io
'Springboot' 카테고리의 다른 글
2021-10-25 (Springboot - JPA - CRUD(2) ) (0) | 2021.10.25 |
---|---|
2021-10-25 (Springboot - JPA - CRUD(1) ) (0) | 2021.10.25 |
2021-10-12 (Springboot - token 로그인 ) (0) | 2021.10.13 |
2021-10-07 (Springboot - board테이블 - 글읽기 수정 ) (0) | 2021.10.07 |
2021-10-07 (Springboot - board테이블 - 글읽기 수정 ) (0) | 2021.10.07 |