암호화


1. jwt.io 홈페이지
- 내가 만든 Jwt 토큰 인코딩 할 수 있다!

HEADER(빨간색 부분)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
결과
//JSON
{
"alg": "HS256",
"typ": "JWT"
}
payload(보라색 부분)-개인정보를 넣지 않는다.(Email,등)
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
//JSON
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
VERIFY SIGNATURE(하늘색 부분)
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)
2. Blog-V4 (리팩토링) JWT 활용
1. User Package
1. UserService(로그인 기능)
public String 로그인(UserRequest.LoginDTO loginDTO) {
//1. 해당 유저가 있는 조회
User user = userRepository.findByUsernameAndPassword(loginDTO.getUsername(), loginDTO.getPassword())
.orElseThrow(() -> new Exception401("인증되지 않았습니다"));
//2. 조회가 되면, JWT 만들고 return 응답하기
String accessToken = JwtUtil.create(user);
return accessToken;
}
- 코드설명
- JWT 생성 (Json Web Token)
JwtUtil.create(user)
는 사용자의 정보를 기반으로 JWT 토큰을 생성하는 메서드입니다.user
객체에는 데이터베이스에서 조회된 사용자의 정보가 포함되어 있고, 이 정보를 사용하여 JWT를 생성합니다.- JWT는 주로 로그인 상태를 유지하거나 인증이 필요한 API 요청 시 사용됩니다. 이 토큰에는 사용자에 대한 정보(예: 아이디, 권한 등)를 안전하게 담을 수 있고, 토큰을 발급받은 후에는 클라이언트가 이를 인증서처럼 사용하게 됩니다.
- accessToken 반환
- 생성된 JWT 토큰을
accessToken
이라는 변수에 저장한 후, 이 값을 반환합니다. return accessToken;
구문을 통해서, 클라이언트에게 토큰을 응답으로 반환합니다.- 클라이언트는 이 토큰을 이후의 요청에 포함시켜 서버에서 인증을 받을 수 있습니다.
정리
- 데이터베이스에서 유저 정보를 조회한 후, 그 정보를 바탕으로 JWT 토큰을 생성합니다.
- 생성된 JWT는 클라이언트에게 반환되며, 이후 클라이언트는 이 토큰을 인증 수단으로 사용할 수 있습니다.
2. UserController
@PostMapping("/login")
public ResponseEntity<?> login(@Valid @RequestBody UserRequest.LoginDTO loginDTO, Errors errors) {
String accessToken = userService.로그인(loginDTO);
return ResponseEntity.ok()
//header를 넣으면 body를 꼭 써줘야한다. Bearer 띄우고 accessToken을 넣어야한다.
.header("Authorization","Bearer"+accessToken)
.body(Resp.ok(null));
}
- 코드설명
1.String accessToken = userService.로그인(loginDTO)
userService
의로그인
메서드를 호출하여, 로그인 정보를 처리하고 JWT 토큰을 생성합니다.
- 이 메서드는 사용자가 입력한 아이디와 비밀번호가 맞는지 검증한 후, 맞다면
accessToken
(JWT)을 생성하여 반환합니다.
2.return ResponseEntity.ok()
- 로그인 성공 시, HTTP 200 OK 상태 코드를 응답으로 보냅니다.
ResponseEntity.ok()
는 HTTP 상태 코드 200을 의미합니다.
3..header("Authorization", "Bearer"+accessToken)
- 응답 헤더에
Authorization
필드를 추가합니다.
- 이
Authorization
필드에Bearer
토큰 방식으로 JWT를 포함합니다.Bearer
와 토큰 사이에 공백이 필요하므로"Bearer "+accessToken
처럼 띄어쓰기가 포함되어 있습니다.
- 클라이언트는 이 헤더를 사용하여 인증이 필요한 다른 요청을 할 때, JWT를 전달하게 됩니다.
4. .body(Resp.ok(null))
- 응답의 본문(Body) 부분에
Resp.ok(null)
를 넣습니다.
- 이 부분에서는 별다른 데이터 없이 응답을 보내기 위해
null
을 넣었지만, 필요에 따라 데이터를 포함할 수도 있습니다.
Resp.ok()
는 일반적으로 표준화된 응답 객체를 만들어주는 헬퍼 메서드로, 성공적인 응답을 나타냅니다.null
을 넣은 이유는 로그인에서 별도로 응답할 데이터가 없기 때문입니다.
정리
- 클라이언트가 로그인 요청을 보내면 서버는 해당 로그인 정보를 검증하고, JWT 토큰을 생성하여
Authorization
헤더에 포함시켜 응답합니다.
- 이후 클라이언트는 이 JWT를 사용하여 다른 보호된 API 요청을 할 수 있게 됩니다.
2. util Package
1. jwtUtil
public class JwtUtil {
public static String create(User user){
String accessToken = JWT.create()
.withSubject("바보")
//유효시간 정하기 7일을 줬다 토큰을 잃어버리면 7일동안 아무것도 할 수 없이 털린다.
.withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7))
.withClaim("id", user.getId())// payload 자리
.withClaim("username", user.getUsername())
.sign(Algorithm.HMAC512("metacoding"));//SIGNATURE 자리
return accessToken;
}
- 코드설명
이 코드는
JwtUtil
클래스에서 JWT(Json Web Token)를 생성하는 메서드입니다. 사용자의 정보를 바탕으로 JWT 토큰을 만들고, 이를 String
형태로 반환합니다. 코드를 하나씩 설명하겠습니다.1. public static String create(User user)
create
메서드는User
객체를 받아서 JWT를 생성하고 반환합니다.
- 이 메서드는 정적(static) 메서드이므로 인스턴스 생성 없이
JwtUtil.create()
로 호출할 수 있습니다.
2. String accessToken = JWT.create()
- JWT 토큰을 생성하기 위한 시작 부분입니다.
JWT.create()
는 JWT 빌더 패턴을 사용하여 토큰을 생성하는 단계입니다.
3. .withSubject("바보")
- JWT의 Subject 필드를 설정합니다. 보통 이 필드는 토큰의 목적이나 사용자와 관련된 식별자 정보를 담는데, 여기서는 문자열
"바보"
로 설정되어 있습니다.
- 이 값은 예시로 사용된 것으로 보이며, 실제 서비스에서는 사용자 아이디나 이메일 같은 유의미한 값을 넣는 것이 좋습니다.
4. .withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7))
- 토큰의 만료 시간을 설정합니다.
withExpiresAt()
메서드를 사용하여 유효 기간을 지정합니다.
- 현재 시간(
System.currentTimeMillis()
)으로부터 7일 후를 만료 시간으로 설정하였습니다.1000 * 60 * 60 * 24 * 7
은 7일을 밀리초로 변환한 값입니다. 1000
: 1초를 밀리초로 변환 (1초 = 1000 밀리초)60
: 1분은 60초60
: 1시간은 60분24
: 하루는 24시간7
: 7일
5. .withClaim("id", user.getId())
- Claim 필드를 추가합니다. JWT의 Claim은 사용자나 애플리케이션 관련 데이터를 담는 영역입니다.
- 여기서는
id
라는 Claim에user.getId()
값을 저장하여, 사용자의 고유 ID를 JWT에 포함시킵니다.
6. .withClaim("username", user.getUsername())
username
이라는 Claim에user.getUsername()
값을 저장하여, 사용자의 이름을 JWT에 포함시킵니다.
7. .sign(Algorithm.HMAC512("metacoding"))
- 토큰에 서명(SIGNATURE)을 추가합니다.
Algorithm.HMAC512("metacoding")
은 HMAC SHA-512 알고리즘을 사용하여 JWT를 서명합니다."metacoding"
은 서명에 사용되는 비밀 키(secret key)로, 서버에서만 알고 있어야 하는 중요한 정보입니다.
- 서명은 토큰의 변조 여부를 검증하는 역할을 하며, 클라이언트가 토큰을 임의로 수정하지 못하게 합니다.
8. return accessToken
- 생성된 JWT 토큰을
String
형태로 반환합니다. 이 토큰은 클라이언트에게 전달되어, 이후 클라이언트가 서버에 요청을 보낼 때 인증 수단으로 사용됩니다.
정리
- 이 코드는
User
객체의 정보를 바탕으로 JWT 토큰을 생성합니다. 토큰에는 사용자 ID와 사용자 이름이 포함되며, 만료 기간은 7일로 설정됩니다.
- 서명에는 HMAC SHA-512 알고리즘을 사용하고, 비밀 키는
"metacoding"
입니다. 생성된 토큰은 클라이언트에게 반환되어 인증 목적으로 사용됩니다.
public static User verify(String jwt){
DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC512("metacoding")).build().verify(jwt);
int id = decodedJWT.getClaim("id").asInt();
String username = decodedJWT.getClaim("username").asString();
return User.builder()
.id(id)
.username(username)
.build();
}
- 코드설명
이 코드는 클라이언트가 제공한 JWT(Json Web Token)를 검증하고, 그 안에 담긴 사용자 정보를 추출하여
User
객체를 반환하는 역할을 합니다. JWT의 서명을 확인하고, Claim에 담긴 정보를 바탕으로 User
객체를 재구성합니다.1. public static User verify(String jwt)
- 이 메서드는 JWT 토큰(
jwt
)을 받아서 검증하고, 그 안의 정보를 바탕으로User
객체를 반환합니다.
- 정적(static) 메서드이므로 클래스 인스턴스 없이도 호출할 수 있습니다.
2. DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC512("metacoding")).build().verify(jwt);
JWT.require(Algorithm.HMAC512("metacoding"))
: JWT 검증을 위한 설정을 만듭니다.HMAC512
알고리즘을 사용하여 서명을 검증하는데, 여기서 비밀 키는"metacoding"
입니다. 이 키는 토큰이 생성될 때 서명에 사용된 키와 동일해야 합니다.
.build()
: 검증기를 빌드하여 검증 준비를 마칩니다.
.verify(jwt)
: 인자로 받은 JWT를 검증합니다. 이 과정에서 토큰의 서명, 유효기간 등이 올바른지 확인하고, 검증이 실패하면 예외가 발생합니다. 검증이 성공하면DecodedJWT
객체를 반환합니다. 이 객체는 토큰의 정보를 담고 있습니다.
3. int id = decodedJWT.getClaim("id").asInt();
- JWT의 Claim 중
"id"
값을 추출합니다. 토큰 생성 시에 포함했던id
Claim을 꺼내고, 이를int
타입으로 변환합니다.
- 이
id
는 사용자의 고유 식별자입니다.
4. String username = decodedJWT.getClaim("username").asString();
- JWT의 Claim 중
"username"
값을 추출합니다. 마찬가지로 토큰 생성 시에 포함했던username
Claim을 꺼내고, 이를String
타입으로 변환합니다.
- 이
username
은 사용자의 이름 또는 ID로 사용됩니다.
5. return User.builder()
User
객체를 빌드하는 과정입니다.
User.builder()
를 사용하여 빌더 패턴을 통해 객체를 생성하고, 이후 사용자 정보를 설정합니다.
6. .id(id)
- 추출한
id
값을User
객체의id
필드에 설정합니다.
7. .username(username)
- 추출한
username
값을User
객체의username
필드에 설정합니다.
8. .build()
User
객체 생성을 완료합니다. 설정한 필드 값들이 반영된User
객체를 반환합니다.
정리
- 이 메서드는 전달된 JWT 토큰을 검증한 후, 토큰 안에 포함된
id
와username
Claim을 추출합니다.
- 추출한 정보를 바탕으로
User
객체를 생성하고 반환합니다.
- 만약 JWT의 서명 검증이 실패하거나, 토큰이 유효하지 않은 경우 예외가 발생합니다.
4o
3. Jwttest
public class Jwttest {
@Test
public void create_test(){
User user = User.builder().id(1).username("ssar").build();
String accessToken = JwtUtil.create(user);
System.out.println(accessToken);
}
// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiLrsJTrs7QiLCJpZCI6MSwiZXhwIjoxNzI3NDAxMDc4fQ.1Ajxs0WTdg40m1CNloFCty1adboo5FpE7qMS0-IfICKFO10xO0u_0dn5R-Cfb9kNdramh15HxGg4kyC7cadJfw
@Test
public void verify_test(){
String accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiLrsJTrs7QiLCJpZCI6MSwiZXhwIjoxNzI3NDAyMTg5LCJ1c2VybmFtZSI6InNzYXIifQ.FyBOadpjVaXKRKw4XiCwIeWz-J7aP8gleudP-7erCkxa1L4iEEKAWG6g8-zhseEtdKcG9etpPqloJxHEyu56PA";
User user = JwtUtil.verify(accessToken);
System.out.println(user.getId());
System.out.println(user.getUsername());
}
}
- 코드설명
1. create_test()
메서드
이 메서드는
JwtUtil.create()
메서드를 테스트하여 JWT를 생성합니다.설명:
- User 객체 생성
User.builder().id(1).username("ssar").build();
로 ID가 1이고 사용자 이름이"ssar"
인User
객체를 생성합니다.
- JWT 생성
JwtUtil.create(user)
를 호출하여user
객체의 정보를 기반으로 JWT 토큰을 생성합니다.
- 토큰 출력
System.out.println(accessToken);
로 생성된 JWT 토큰을 콘솔에 출력합니다.- 출력된 JWT는 나중에 검증에 사용할 수 있습니다.
이 테스트는
JwtUtil.create()
가 정상적으로 작동하여 JWT 토큰을 올바르게 생성하는지 확인하는 역할을 합니다.verify_test()
메서드
이 메서드는
JwtUtil.verify()
메서드를 테스트하여 JWT를 검증하고, JWT에 포함된 사용자 정보를 제대로 추출하는지 확인합니다.설명:
- JWT 토큰 준비
- 문자열로 JWT 토큰을 하드코딩하여
accessToken
변수에 저장합니다. 이 토큰은 실제create_test()
에서 생성된 것과 비슷한 형식입니다.
- JWT 검증 및 사용자 정보 추출
JwtUtil.verify(accessToken)
을 호출하여 JWT를 검증합니다. 검증에 성공하면 JWT에 포함된 사용자 정보를 추출하여User
객체로 변환합니다.
- 사용자 정보 출력
System.out.println(user.getId());
와System.out.println(user.getUsername());
를 통해User
객체에서id
와username
을 추출하여 출력합니다.- 이 정보는 JWT에 포함된 클레임(Claim)에서 온 값입니다.
이 테스트는
JwtUtil.verify()
메서드가 정상적으로 JWT를 검증하고, JWT에서 사용자 정보를 올바르게 추출하는지 확인하는 역할을 합니다.요약
create_test()
:User
객체 정보를 기반으로 JWT를 생성하고 이를 콘솔에 출력하여 토큰 생성 기능을 테스트합니다.
verify_test()
: 미리 정의된 JWT를 검증하고 그 안에 포함된 사용자 ID와 사용자 이름을 추출하여 출력하는 방식으로 검증 기능을 테스트합니다.
이 두 테스트는 JWT 생성과 검증 로직이 의도한 대로 동작하는지 확인하는 데 유용합니다.
4. Postman 이용하기(이제부터 HTML,Mustache를 사용 안 함, 백엔드만 하기)

Share article