Lambda에서 Cognito 인증 (사용자 인증)

13039 단어 람다cognitoAWS

소개



SDK를 로컬로 가져와서 괴롭히는 샘플은 검색에 걸립니다만,
클라우드 측 (Lambda 함수 내부)에서 완료되는 샘플을 찾을 수 없습니다 ...
좋아, 그렇다면 게시합니다.

상단
사용자 작성
사용자 확인
사용자 인증
└사용자 허가 ←이마코코

주의사항



이 논문은 Lambda 함수로 이 기사을 구현하는 것을 목표로합니다.
형제 기사와는 모색이 다르기 때문에, 미리 양해 바랍니다.

  • Decode and verify Amazon Cognito JWT tokens (Amazon Cognito JWT 토큰을 해독하고 확인) 를 자바스크립트로 수정한 프로그램을 사용하십시오.
  • npm을 사용하여 라이브러리를 얻고 Lambda에 업로드하는 단계를 포함합니다.
  • Lambda 함수에서 API Gateway에 대한 권한 부여자를 만드는 방법을 설명하는 기사가 아닙니다.
  • API Gateway에서 권한 부여자를 설정하는 방법을 설명하는 기사도 아닙니다. →이쪽을 봐 주세요.

  • 사용자 권한 부여(Authorization)



    통지된 ID 토큰이 유효한지 여부를 판별합니다.

    일반적으로 사용자 허가는 API Gateway 권한 부여자에게 맡겨야 합니다.

    이 글에서는 Lambda 함수로 사용자 권한을 부여하는 방법을 설명합니다.

    문서



    AWSJavaScriptSDK는 사용하지 않습니다.
    JSON 웹 토큰 확인

    npm



    사용자 권한 부여에 사용할 외부 라이브러리를 얻습니다.

    외부 라이브러리



    npm에서 구합니다.
    얻은 외부 라이브러리는 Lambda에 업로드합니다.
    npm i jwk-to-pem --save
    npm i jsonwebtoken --save
    

    Cognito



    Cognito 사용자 풀에서 사용자 권한 부여에 사용할 '공개 키'와 '앱 클라이언트 ID'를 가져옵니다.

    공개 키



    공개 키는 여기에 있습니다.
    https://cognito-idp.{리전}.amazonaws.com/{풀 ID}/.well-known/jwks.json

    풀 ID는 Cognito 사용자 풀의 일반 설정 페이지에서 확인할 수 있습니다.


    앱 클라이언트 ID



    앱 클라이언트 ID는 Cognito 사용자 풀의 '일반 설정 > 앱 클라이언트' 페이지에서 확인할 수 있습니다.


    람다



    함수를 처음부터 만듭니다.

    환경설정



    궁극적으로는 다음과 같은 환경으로 합니다.


    소스 코드



    ↓ 적당한 예외를 throw하고 있습니다.
    앱 클라이언트 ID나 발행자(issuer)의 문자열은 Lambda의 환경 변수로 설정하면 프로그램의 전망이 좋아진다고 생각합니다.

    authorizer.js
    'use strict';
    
    // ライブラリ
    const jwkToPem = require('./node_modules/jwk-to-pem/src/jwk-to-pem.js');
    const jsonwebtoken = require('./node_modules/jsonwebtoken');
    // 公開キー。 https://cognito-idp.{リージョン}.amazonaws.com/{プールID}/.well-known/jwks.json と同じもの
    const jwks = require('./jwks.json');
    // JWT形式判定用の正規表現
    const jwtRe = /(?<header>.+)\.(?<payload>.+)\.(?<signature>.+)/;
    
    /**
     * オーソライザー (トークンを検証する)
     * @param {string} token IDトークン
     * @returns {Object} ペイロード
     */
    module.exports = token => {
    
      // 入力はJWT形式の文字列か?
      const match = jwtRe.exec(token);
      if (!match) throw 'AuthError';
    
      // ヘッダー情報を取得
      const header = JSON.parse(Buffer.from(match.groups.header, 'base64').toString());
    
      // 公開キーから使用するキーを選ぶ
      const jwk = jwks.keys.find(k => k.kid == header.kid);
      if (!jwk) throw 'AuthError';
    
      // 外部ライブラリを使って署名を確認する
      const pem = jwkToPem(jwk);
      const claim = jsonwebtoken.verify(token, pem);
    
      // 有効期限の確認
      const now = new Date() / 1000;
      if (now > claim.exp || now < claim.auth_time) throw 'AuthError';
    
      // 利用者(audience)の確認
      if (claim.aud !== '{アプリクライアントID}')  throw 'AuthError';
    
      // 発行者(issuer)の確認
      if (claim.iss !== 'https://cognito-idp.{リージョン}.amazonaws.com/{プールID}') throw 'AuthError';
    
      // トークン種別の確認
      // IDトークンを使う場合の claim.token_use は 'id'
      // アクセストークンを使う場合の claim.token_use は 'access'
      if (claim.token_use !== 'id') throw 'AuthError';
    
      // ハレて認可された
      return claim;
    };
    

    ↓예외를 catch하고 있지 않습니다만, 그 근처를 포함해 적당하게 개변해 주세요.

    index.js
    'use strict';
    
    // オーソライザー
    const authorizer = require('./authorizer.js');
    
    /**
     * メイン
     * @param {Object} event プロキシ統合の情報
     * @returns {Promise<HTTPResponse>} HTTPレスポンス
     */
    exports.handler = async event => {
    
      // event情報からIDトークンを取得
      const token = event.headers['Authorization']; // HTTPヘッダーのAuthorizationにIDトークンがある場合の例
    
      // IDトークンをオーソライザーに投入
      const claim = authorizer(token);
    
      // 例外が発生しなければ認可成功
    
      // HTTPレスポンスを返して終了
      return {
        statusCode: 200,
        body: 'Authorization succeeded.',
      };
    };
    

    좋은 웹페이지 즐겨찾기