배경지식
사용자 인증
- 사용자가 백엔드에 접근할 때 그 사용자가 누구인지, 유효한 사용자인지를 검증해야 한다.
- 크게보면 사용자 정보를 쿠키, 세션, 토큰을 사용해 인증을 하게된다.
Cookie 인증
- 사용자를 인증했을 때 서버에서 사용자에게 쿠키를 전송하고, 해당 쿠키 데이터를 바탕으로 하여 사용자를 인증하는 방식이다.
- 클라이언트 측에서 별 신경을 쓰지 않아도 알아서 인증정보를 전송할 수 있다는 장점이 있다.
- 하지만 브라우저 간 쿠키 공유가 어렵고, 쿠키값을 평문으로 저장하기 때문에 데이터 탈취의 위험이 있다는 단점이 있다.
Session 인증
- Cookie 인증과 비슷하지만, 서버의 메모리에 대부분의 정보를 저장하고, 클라이언트에는 세션 id만을 저장하는 방식이다.
- 쿠키를 사용하는 방법보다 보안면에서 낫지만, 서버의 부하가 증가하고, 여전히 세션 id를 탈취해 다른 사용자인 척 속일 수 있다는 문제점이 있다.
Token 인증
- 쿠키와 세션 인증 방법을 절충한 방법으로, 인증에 필요한 사용자 정보와 토큰 검증에 필요한 데이터를 담아 클라이언트에 전달하는 방식이다.
- 서버에서는 클라이언트에서 전달받은 데이터를 받아 토큰의 위조여부를 검증한다.
- 데이터를 클라이언트가 저장하기 때문에 서버의 부하를 줄일 수 있고, 사용기한을 짧게 설정함으로써 보안성을 강화할 수 있다.
- 하지만 토큰 데이터가 길어 요청이 많으면 네트워크 부하가 심해지며, Payload는 암호화되지 않기 때문에 사용자의 민감한 정보를 담을 수 없다는 단점을 가지고 있다.
JWT

AWS amplify에서 cognitio를 활용한 JWT 인증 사용하기
- 그럼 이제 aws amplify 서비스에서 JWT 토큰을 활용한 인증을 사용하는 법을 알아보자.
- 클라이언트에서 직접 aws 서비스에 접근하는 경우에는 별도의 설정을 하지 않고 amplify에서 제공하는 함수만으로 인증 처리를 해줄 수 있다.
- 하지만 lambda나 next.js 등의 서버리스 함수를 거치는 경우에는 별도로 토큰을 제출하고, 검증하는 작업을 걸쳐야 한다.
- Cognitio를 사용한 경우 시크릿 키를 직접 보관하는것이 아니라 aws 서비스에 저장하기 때문에, 이를 가져올 라이브러리 역시 필요하다.
Frontend
- 프론트엔드에서는 amplify 라이브러리를 통해 jwt 토큰을 가져올 수 있다.
import { Auth } from "aws-amplify";
export default async function getCurrentUserToken() {
try {
const currentSession = await Auth.currentSession();
const accessToken = currentSession.getAccessToken();
const jwt = accessToken.getJwtToken();
return jwt;
} catch (error) {
console.log(error);
return "";
}
}
- 이 값을 인증이 필요한 곳에 header로 전송해주면 된다.
- 인증 프로토콜은
<type> <credentials>
형식을 가지기 때문에 앞에 type이름으로 Bearer를 붙여줘야 한다.
export default async function getPostInfo(
id: string,
): Promise<PostData> {
try {
const token = await getCurrentUserToken();
const result = await fetch(`${process.env.NEXT_PUBLIC_API_DOMAIN}/categories/${id}`, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
});
const { post }: { post: PostData } = await result.json();
return post;
} catch (error) {
throw error;
}
}
Backend
- Node.js 환경에서는 jwt 토큰 검증을 위해 aws-jwt-verify 사용을 권장하고 있다.
npm i aws-jwt-verify
- 인증 조건을 담은 verifier 객체를 생성하고, 받아온 토큰값을 검증하는 함수를 사용해주면 간단하게 토큰 검증을 수행할 수 있다.
import { CognitoJwtVerifier } from "aws-jwt-verify";
export default async function verifyToken(token: string | null) {
const [tokenType, tokenText] = tokenString.split(" ");
if (tokenType !== "Bearer") {
throw new Error(ErrorMessage.INVALID_TOKEN_TYPE);
}
const verifier = CognitoJwtVerifier.create({
userPoolId: "ap-northeast-2_mollu"
tokenUse: "access",
clientId: "d30lguc62630ad"
});
try {
const payload = await verifier.verify(
tokenText
);
console.log("Token is valid!);
return userID;
} catch (error) {
console.log(error);
throw new Error("Token is not valid...");
}
}
출처:
https://docs.aws.amazon.com/ko_kr/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html