يقوم cognito-express بمصادقة طلبات واجهة برمجة التطبيقات (API) على تطبيق Node.js (إما الذي يعمل على خادم أو في وظيفة AWS Lambda) عن طريق التحقق من توقيع JWT الخاص بـ AccessToken
أو IDToken
الذي تم إنشاؤه بواسطة Amazon Cognito.
تتيح لك هذه الوحدة مصادقة طلبات Node.js API من خلال التحقق من توقيع JWT الخاص بـ AccessToken
أو IDToken
- دون الحاجة إلى الاتصال بـ Amazon Cognito لكل استدعاء لواجهة برمجة التطبيقات.
يمكن دمج الوحدة بسهولة وبشكل غير مخفي في أي تطبيق أو إطار عمل يدعم البرامج الوسيطة ذات نمط الاتصال، بما في ذلك Express.
تجمع هذه الوحدة بشكل أساسي الخطوات من 1 إلى 7 المدرجة في وثائق AWS الرسمية حول استخدام رموز المعرف ورموز الوصول في واجهات برمجة تطبيقات الويب الخاصة بك
iss
. يجب أن يتطابق مع تجمع المستخدمين الخاص بك.tokenUse
. يجب أن يتطابق مع تفضيلاتك المحددة access
أو أنواع الرموز المميزة id
يمكنك الآن الوثوق بالمطالبات الموجودة داخل الرمز المميز واستخدامها بما يناسب متطلباتك.
بعد المصادقة الناجحة للمستخدم، يصدر Amazon Cognito ثلاثة رموز مميزة للعميل:
(ملاحظة: لا تغطي هذه الوحدة آلية تسجيل الدخول وسيتعين عليك إنشاء ذلك بشكل منفصل)
احفظ هذه الرموز المميزة داخل تطبيق العميل (ويفضل أن تكون على شكل ملفات تعريف الارتباط). عند استدعاء أي واجهة برمجة تطبيقات من العميل، قم بتمرير 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 ) ;
}
) ;
} ) ;
غاري أرورا
معهد ماساتشوستس للتكنولوجيا