cognito express
2023
cognito-express는 Amazon Cognito에서 생성된 AccessToken
또는 IDToken
의 JWT 서명을 확인하여 Node.js 애플리케이션(서버 또는 AWS Lambda 함수에서 실행)에서 API 요청을 인증합니다.
이 모듈을 사용하면 API 호출마다 Amazon Cognito를 호출할 필요 없이 AccessToken
또는 IDToken
의 JWT 서명을 확인하여 Node.js API 요청을 인증할 수 있습니다.
이 모듈은 Express를 포함하여 Connect 스타일 미들웨어를 지원하는 모든 애플리케이션이나 프레임워크에 쉽고 눈에 띄지 않게 통합될 수 있습니다.
이 모듈은 기본적으로 웹 API에서 ID 토큰 및 액세스 토큰 사용에 대한 공식 AWS 설명서에 나열된 1~7단계를 번들로 제공합니다.
iss
클레임을 확인하세요. 사용자 풀과 일치해야 합니다.tokenUse
클레임을 확인하세요. access
또는 id
토큰 유형에 대해 설정된 기본 설정과 일치해야 합니다.이제 토큰 내부의 클레임을 신뢰하고 요구 사항에 맞게 사용할 수 있습니다.
사용자 인증에 성공하면 Amazon Cognito는 클라이언트에 세 가지 토큰을 발급합니다.
(참고: 로그인 메커니즘은 이 모듈에서 다루지 않으므로 별도로 빌드해야 합니다.)
클라이언트 앱 내에 이러한 토큰을 저장합니다(가급적 쿠키로). 클라이언트에서 API가 호출되면 AccessToken
또는 IDToken
서버에 전달합니다.
AccessToken
또는 IDToken
을 전달하는 방법은 전적으로 귀하에게 달려 있습니다. 다음은 두 가지 옵션입니다.
//Initializing CognitoExpress constructor
const cognitoExpress = new CognitoExpress ( {
region : "us-east-1" ,
cognitoUserPoolId : "us-east-1_dXlFef73t" ,
tokenUse : "access" , //Possible Values: access | id
tokenExpiration : 3600000 //Up to default expiration of 1 hour (3600000 ms)
} ) ;
cognitoExpress . validate ( accessTokenFromClient , function ( err , response ) {
if ( err ) {
/*
//API is not authenticated, do something with the error.
//Perhaps redirect user back to the login page
//ERROR TYPES:
//If accessTokenFromClient is null or undefined
err = {
"name": "TokenNotFound",
"message": "access token not found"
}
//If tokenuse doesn't match accessTokenFromClient
{
"name": "InvalidTokenUse",
"message": "Not an id token"
}
//If token expired
err = {
"name": "TokenExpiredError",
"message": "jwt expired",
"expiredAt": "2017-07-05T16:41:59.000Z"
}
//If token's user pool doesn't match the one defined in constructor
{
"name": "InvalidUserPool",
"message": "access token is not from the defined user pool"
}
*/
} else {
//Else API has been authenticated. Proceed.
res . locals . user = response ; //Optional - if you want to capture user information
next ( ) ;
}
} ) ;
비동기/대기 패턴도 지원합니다.
( async function main ( ) {
try {
const response = await cognitoExpress . validate ( accessTokenFromClient ) ;
console . log ( response ) ;
//User is authenticated, proceed with rest of your business logic.
} catch ( e ) {
console . error ( e ) ;
//User is not authenticated, do something with the error.
//Perhaps redirect user back to the login page
}
} ) ( ) ;
//app.js
"use strict" ;
const express = require ( "express" ) ,
CognitoExpress = require ( "cognito-express" ) ,
port = process . env . PORT || 8000 ;
const app = express ( ) ,
authenticatedRoute = express . Router ( ) ; //I prefer creating a separate Router for authenticated requests
app . use ( "/api" , authenticatedRoute ) ;
//Initializing CognitoExpress constructor
const cognitoExpress = new CognitoExpress ( {
region : "us-east-1" ,
cognitoUserPoolId : "us-east-1_dXlFef73t" ,
tokenUse : "access" , //Possible Values: access | id
tokenExpiration : 3600000 //Up to default expiration of 1 hour (3600000 ms)
} ) ;
//Our middleware that authenticates all APIs under our 'authenticatedRoute' Router
authenticatedRoute . use ( function ( req , res , next ) {
//I'm passing in the access token in header under key accessToken
let accessTokenFromClient = req . headers . accesstoken ;
//Fail if token not present in header.
if ( ! accessTokenFromClient ) return res . status ( 401 ) . send ( "Access Token missing from header" ) ;
cognitoExpress . validate ( accessTokenFromClient , function ( err , response ) {
//If API is not authenticated, Return 401 with error message.
if ( err ) return res . status ( 401 ) . send ( err ) ;
//Else API has been authenticated. Proceed.
res . locals . user = response ;
next ( ) ;
} ) ;
} ) ;
//Define your routes that need authentication check
authenticatedRoute . get ( "/myfirstapi" , function ( req , res , next ) {
res . send ( `Hi ${ res . locals . user . username } , your API call is authenticated!` ) ;
} ) ;
app . listen ( port , function ( ) {
console . log ( `Live on port: ${ port } !` ) ;
} ) ;
//client.js - angular example
"use strict" ;
//I stored my access token value returned from Cognito in a cookie called ClientAccessToken
app . controller ( "MyFirstAPI" , function ( $scope , $http , $cookies ) {
$http ( {
method : "GET" ,
url : "/api/myfirstapi" ,
headers : {
accesstoken : $cookies . get ( "ClientAccessToken" )
}
}
} ) . then (
function success ( response ) {
//Authenticated. Do something with the response.
} ,
function error ( err ) {
console . error ( err ) ;
}
) ;
} ) ;
게리 아로라
MIT