cognito express
2023
cognito-express 透過驗證 Amazon Cognito 產生的AccessToken
或IDToken
的 JWT 簽名,對 Node.js 應用程式(在伺服器上執行或在 AWS Lambda 函數中執行)上的 API 請求進行身份驗證。
此模組可讓您透過驗證AccessToken
或IDToken
的 JWT 簽章來對 Node.js API 請求進行身份驗證,而無需為每個 API 呼叫呼叫 Amazon Cognito。
此模組可輕鬆、不顯眼地整合到任何支援 Connect 式中間件(包括 Express)的應用程式或框架中。
此模組本質上捆綁了有關在 Web API 中使用 ID 令牌和存取權杖的 AWS 官方文件中列出的步驟 1-7
iss
聲明。它應該與您的用戶池匹配。tokenUse
聲明。它應該符合您對access
或id
令牌類型的設定首選項現在您可以信任令牌內的聲明並根據您的要求使用它。
成功驗證使用者身分後,Amazon Cognito 向客戶端頒發三個令牌:
(注意:該模組不包含登入機制,您必須單獨建置它)
將這些令牌保存在客戶端應用程式中(最好是作為 cookie)。當客戶端呼叫任何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 ) ;
}
) ;
} ) ;
加里·阿羅拉
麻省理工學院