https://jwt.io/introduction (공식 문서)
https://velopert.com/2389 (Velog 만드신 분의 블로그)
{{HEADER}}.{{PAYLOAD}}.{{SIGNATURE}}
{{HEADER}}{
"alg": "HS256",
"typ": "JWT"
}
"HS256"은 HMAC SHA256"typ": Token type"JWT"'{"alg": "HS256","typ": "JWT"}'가 인코딩되는 것.{{PAYLOAD}}{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
iss: issuersub: subjectiat: issued atexp: expiration time1480849147370 등 NumericDate 형식이어야 한다.nbf: not beforeaud: audiencejti: jwt id{
"http(s)://specific.uri/@unique_recommended_namespace/additional_path": true
}
{
"https://velopert.com/jwt_claims/is_admin": true
}@unique_recommended_namespace)를 포함하는 URI{
"username": "ajisai"
}
{
"iss": "velopert.com",
"exp": "1485270000000",
"https://velopert.com/jwt_claims/is_admin": true,
"userId": "11028373727102",
"username": "velopert"
}
Predefined, Public, Private을 혼용해도 된다.
=가 붙기도 하고 안 붙기도 한다.=는 query string에 쓰이므로 URL-safe하지 않다.{{SIGNATURE}}HMACSHA256( //Pseudocode
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
secretBase64(ENCRYPT(hash(base64(HEADER).base64(PAYLOAD), SECRET))//Header
const header = {
"typ": "JWT",
"alg": "HS256"
};
const encodedHeader = new Buffer(JSON.stringify(header))
.toString('base64')
.replace('=', ''); //remove padding
//Payload
const payload = {
"iss": "velopert.com",
"exp": "1485270000000",
"https://velopert.com/jwt_claims/is_admin": true,
"userId": "11028373727102",
"username": "velopert"
};
const encodedPayload = new Buffer(JSON.stringify(payload))
.toString('base64')
.replace('=', '');
//Signature
const crypto = require('crypto');
const signature = crypto.createHmac('sha256', 'SECRET')
.update(encodedHeader + '.' + encodedPayload)
.digest('base64')
.replace('=', '');
const jwt = encodedHeader + "." + encodedPayload + "." + signature;
중간중간에 해시나 인코딩은 라이브러리가 해준다면 직접 할 필요는 없다.
401 Unauthorized가 응답으로 돌아온다.401이 응답된다.header.payload를 암호화한 것결론적으로 현재 payload에 포함된 expired date(조작됨)와 signature에 포함된 expired date(조작되지 않았음)가 맞지 않으므로 서버는 access 권한을 주지 않는다.
여기를 참고 바랍니다.