인증과 인가
인증(authentication) : 말그대로 인증하는 것, 로그인
인가(authorization) : 인증을 받은 사용자가 서비스를 이용하려할 때 허가해주는 것
헤더(header)와 페이로드(payload), 서명(signature) 3부분으로 이루어 졌으며 각각의 부분은 인코딩 혹은 암호화가 되어 있다.
[header].[payload].[signature]
{
"alg": "HS256", // 알고리즘, 서명 값을 만드는 데 사용될 알고리즘이 저장됨
"typ": "JWT" // 타입, 고정값
}
claim이 포함되어 있는 부분{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
npm install jsonwebtoken
jwt.sign(payload, secretOrPrivateKey, [options, callback])
토큰 생성 유틸리티
import jwt from "jsonwebtoken";
export class GenerateTokenUtil {
private secretKey: string;
constructor(secretKey: string) {
this.secretKey = secretKey;
}
public generateToken(id: number, nickname: string, expiresIn: string) {
const payload = {
id: id,
nickname: nickname,
};
const token = jwt.sign(payload, this.secretKey, { expiresIn: expiresIn });
return token;
}
}
jwt.verify(token, secretOrPublicKey, [options, callback])
발급된 토큰을 검증하는 미들웨어
export const tokenValidator = (
req: Request,
res: Response,
next: NextFunction
) => {
const authorizationHeader = req.headers.authorization;
if (authorizationHeader && authorizationHeader.startsWith("Bearer ")) {
const token = authorizationHeader.slice(7); // "Bearer " 부분을 제외한 나머지 문자열을 추출
try {
const decodedToken = jwt.verify(token, process.env.SECRET_KEY!);
req.decoded = decodedToken; // 토큰의 복호화된 데이터 저장
next(); // 다음 미들웨어로 이동
} catch (error) {
console.log(error);
throw new CustomError("유효하지 않은 토큰입니다.", HttpCode.UNAUTHORIZED);
}
} else {
throw new CustomError("토큰이 존재하지 않습니다.", HttpCode.NOT_FOUND);
}
};
https://jwt.io/introduction
https://www.daleseo.com/jwt/
https://www.npmjs.com/package/jsonwebtoken