구현 내용 (시큐리티 통합 주제로)
1. JWT 인증 로직 구현
2. 패스워드 암호화 로직 구현
1. JWT 생성 및 반환 구현
사용자 정보를 바탕으로 헤더와 페이로드를 작성하고 전자 서명한 후 토큰을 리턴하도록 해야합니당
구현을 위해 JWT 관련 라이브러리를 디펜던시에 추가해야해요!
build.gradle의 dependencies 부분에 jjwt 라이브러를 추가해줍시닷!
// https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt
implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'
이제 보안을 제대로 구현하기위해 security 패키지를 만듭시다!!

이 패키즈는 인증과 인가를 위한 모든 클래스를 관리하게 해줍시다!!
그리고 security 패키지니 안에 TokenProvider 클래스를 만들어 주어야 합니다.
이 클래스가 하는일은 사용자 정보를 받아 JWT를 생성하는 일입니다!
package com.unoSpringBoot.study.security;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import org.springframework.stereotype.Service;
import com.unoSpringBoot.study.model.UserEntity;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class TokenProvider {
private static final String SECRET_KEY = "NMA8JPcFuna59f5";
public String create(UserEntity userEntity) {
Date expirDate = Date.from(Instant.now().plus(1, ChronoUnit.DAYS));
/*
* {//header "alg" : "HS512" }.
* { //payload
* "sub" : "40288093784915d201784916a40c001"
* , "iss" : "demo app"
* , "iat" : 1595733657
* , "exp" : 1596597657
* }.
*/
//JWT 토큰 생성
return Jwts.builder()
//header에 들어갈 내용 및 서명을 하기 위한 secret_key
.signWith(SignatureAlgorithm.HS512, SECRET_KEY)
//payload에 들어갈 내용
.setSubject(userEntity.getId())
.setIssuer("demo app").setIssuedAt(new Date()).setExpiration(expirDate).compact();
}
public String validateAndGetUserId(String token) {
// parseClaimsJwt 매서드가 Base64로 디코딩 및 파싱
// 해더와 페이로드를 setSigninKey 로 넘어온 시크릿을 이용해 서명한 후 token의 서명과 비교
// 위조 되지 않았다면 페이로드(Claims)리턴, 위조라면 예외를 날림
// 그중 우리는 userId가 필요하므로 getBody를 부른다.
Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
return claims.getSubject();
}
}
이렇게 작성해 주었다.
보기보다 간단하다. 첫번째 메서드 create는 JWT 라이브러리를 이용해 JWT 토큰을 생성한다.
두번째 메서드는 validateAndGetUserId()토큰을 디코딩 및 파싱하고 토큰의 위조 여부를 확인한다.
이후 우리가 원하는 subject, 즉 사용자의 아이디를 리턴한다.
라이브러리 덕에 우리가 굳이 Json을 생성, 서명, 인코딩, 디코딩, 파싱 하는 작업을 하지않아도 됩니다!!

위 코드를 참고해서 TokenProvider를 작성했다면
이제 로그인 부분에서 TokenProvider를 이용해 토큰을 생성한 후 UserDTO에 이를 반환해야합니다!!

어렵다... 천천히 코드를 짜고 설명드리겠습니다.
우선 기존의 SO 서비스단의 /signin <- 로그인하는 URI
를 수정해주어야합니다.
여긴 문제가 없으니 이제 컨트롤 오브젝트로 들어갑니다.
package com.unoSpringBoot.study.Controller.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import com.unoSpringBoot.study.DTO.ResponseDTO;
import com.unoSpringBoot.study.DTO.UserDTO;
import com.unoSpringBoot.study.model.UserEntity;
import com.unoSpringBoot.study.security.TokenProvider;
import com.unoSpringBoot.study.service.UserService;
@Service
public class LoginUserCO {
@Autowired
private TokenProvider tokenProvide;
@Autowired
private UserService service;
public ResponseEntity<?> authenticate(UserDTO userDTO) {
UserEntity user = service.getByCredentials(userDTO.getEmail(), userDTO.getPassword());
if (user != null) {
// 여기서 부터 토큰생성을 해주는 기능을 넣어준다!
final String token = tokenProvide.create(user);
final UserDTO responseUserDTO = UserDTO.builder()
.email(user.getUsername()).id(user.getId()).token(token).build();
return ResponseEntity.ok().body(responseUserDTO);
} else {
ResponseDTO<?> responseDTO = ResponseDTO.builder().error("로그인 실패 ㅠ").build();
return ResponseEntity.badRequest().body(responseDTO);
}
}
}
수정된 부분은 크게없고 토큰을 만들어주는 토큰프로바리드와 해당 메서드, 그리고 그 토큰을 저장시켜주는
.toke(token)을 builder()뒤에 줄줄이 달아줍시다!
작성을 완료했으면 테스트를통해서 확인해줍시다!!
토큰을 테스트하려면
애플리케션을 실행시키고 포스트맨에서 localhost:8080/auth.signup에 HTTP POST 매서드 요청을 보내
계정을 우선 생성해 주어야합니다!!
-아직 DB구축이 ㅠ
raw 에 제이슨형태로 지정해주는것 꼭 잊지맙시다~~
{
"email" : "zhfldk014745@naver.com",
"username" : "unokim",
"password" : "1234"
}
결과를 얻었다 . 지금 회원가입이 성공했다는 것이다. 이제 로그인을 해봅시다!!
localhost:8080/auth/signin 으로 고곸!!

{
"token" : "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI0MDI4ODA4YjdkOWE1MTA3MDE3ZDlhNTUzODEyMDAwMyIsImlzcyI6ImRlbW8gYXBwIiwiaWF0IjoxNjM4OTcyMDEwLCJleHAiOjE2MzkwNTg0MTB9.2vJaGtHuW_yVmLCTowBgj0herZ7tYnpXxtN5uuFdXGlzE5a6_hZlQTDIGr5xy1BFZ3N-Z_GOkrUFOIwRP4hO5g"
, "email": "unokim"
, "username": null
, "password": null
, "id": "4028808b7d9a5107017d9a5538120003"
, "auth": null
}
'Spring boot 프로젝트 기록 > 3. 인증 백엔드 통합' 카테고리의 다른 글
패스워드 암호화 (0) | 2021.12.13 |
---|---|
TodoController에서 인증된 사용자 사용하기 (0) | 2021.12.12 |
JWT 를 이용한 인증 구현 (0) | 2021.12.12 |
REST security를 구현해보자! (0) | 2021.12.02 |
댓글