Cognito-express ตรวจสอบสิทธิ์คำขอ API บนแอปพลิเคชัน Node.js (ไม่ว่าจะทำงานบนเซิร์ฟเวอร์หรือในฟังก์ชัน AWS Lambda) โดยการตรวจสอบลายเซ็น JWT ของ AccessToken
หรือ IDToken
ที่สร้างโดย Amazon Cognito
โมดูลนี้ช่วยให้คุณตรวจสอบสิทธิ์คำขอ Node.js API ได้โดยการตรวจสอบลายเซ็น JWT ของ AccessToken
หรือ IDToken
โดยไม่จำเป็นต้องเรียก Amazon Cognito สำหรับการเรียกใช้ API แต่ละรายการ
โมดูลสามารถรวมเข้ากับแอปพลิเคชันหรือเฟรมเวิร์กใดๆ ที่รองรับมิดเดิลแวร์แบบ Connect ได้อย่างง่ายดายและไม่เกะกะ รวมถึง Express
โมดูลนี้จะรวมขั้นตอนที่ 1-7 ที่ระบุไว้ในเอกสาร AWS อย่างเป็นทางการเกี่ยวกับการใช้โทเค็น ID และโทเค็นการเข้าถึงใน Web API ของคุณ
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/await ด้วย
( 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 ) ;
}
) ;
} ) ;
แกรี่ อาโรร่า
เอ็มไอที