Amazon API Gateway CORS の有効化

API Gateway CORS有効

Amazon API Gateway がブラウザコンソール画面から[リソース|アクション]「CORS の有効化」画面内[CORS を有効にして既存の CORS ヘッダーを置換]ボタンをクリックすることでCORS有効化されます。然しメソッドの実行設定でLambdaを指定しLambda プロキシ統合の使用」チェックしてしまうと「CORS の有効化」が機能しなくなるようです。これはLambda側にヘッダーの制御が渡ったということだと、私は解釈しています。従って、Lambda側でコード内にHTTPヘッダーを書きCORSを有効にする記述をすればCORSとして利用できます。

「Lambda プロキシ統合の使用」をOFFにした場合HTTPヘッダーを確認すると「access-control-allow-origin: *」がついていました。
「Lambda プロキシ統合の使用」をOFFにした場合HTTPヘッダーを確認すると「access-control-allow-origin: *」がついていました。

Lambda プロキシ統合の使用」をONにした場合、access-control-allow-originが消えてしまいブラウザからAjaxなどでAPIのデータが取得できなくなります。API Gatewayの「Lambda プロキシ統合の使用」をONにした場合はLambda側で下記のように記述します。

exports.handler = async (event) => {
    // TODO implement
    const response = {
        headers: {
            "Access-Control-Allow-Origin" : "*", 
            "Access-Control-Allow-Credentials" : true
        }, 
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};

headersというエレメントを追加し“Access-Control-Allow-Origin”“Access-Control-Allow-Credentials”を追加します。ヘッダーを確認すると下記のように2行が追加されていました。

Lambda側でCORS HTTPヘッダーを追加
Lambda側でCORS HTTPヘッダーを追加

上記の処理を行いHTTPヘッダーに上記文字列の確認ができれば、Ajaxなどからデータ取得できます。

Node.js 12 Lambdaで HTTPClient (request)を使う方法

Node.js 12 LambdaでHTTPClientを使う

Node.jsでWebAPIなどの外部サービスへ接続する際「request」と云う使いやすいHTTP clientがあります。requestパッケージはnpmコマンドでインストールできます。ローカルで実行する場合は下記コードのように記述できます。

const request = require("request")
request.get('https://mjeld.com/', (err, resp, b1) => {
    if (!err) {
        console.log(resp)
    }
})    

コード内のconsole.log(resp)部分でWebから取得した文字列を問題なく出力できます。然し、AWSLambdaを使う場合上記のようなノンブロッキングの処理ではexports.handlerに返信できません。Lambdaの場合は、awaitPromiseを使って関数内のreturnでデータを返せるように記述します。

const request = require("request")

exports.handler = async (event) => {
    // TODO implement
    const response = {
        statusCode: 200,
        body: JSON.stringify(await new Promise((resolve, reject) => {
            request.get('https://mjeld.com/', (err, resp, b1) => {
                if (err) {
                    reject(err)
                } else {
                    resolve(resp)
                }
            })    
        })),
    };
    return response;
};

上記コードはLambdaのデフォルトで入っているexports.handler = async (event) => {}内でrequestで取得したGETデータをreturnで返す処理です。Lambdaのデフォルトではresponse.body = ‘Hello from Lambda!’と書いているのですが、その部分を置き換えています。

この方法を応用すれば、AWS Lambdaにノンブロッキングのパッケージを利用することもできます。

AWSからSMS(ショートメール)を送信する

AWSからSMS送信

SMS(ショートメール)は電話番号を宛先として短い文章を送信できる仕組みです。最近では、本人確認のためSMS(ショートメール)を使った二段階認証を用いたシステムも増えてきています。AWSでは「Amazon Simple Notification Service」というサービスが提供されていて誰でも簡単にSMS送信を試すことができます。下記はNode.jsを使ったSMS送信例です。

const AWS = require('aws-sdk');

exports.handler = async (event) => {
    let sns1 = new AWS.SNS({region : "ap-northeast-1"})
    return await sns1.publish(event).promise()
}

let aTest = exports.handler({
    Message : "Mjeld Technologies \n認証コード: xxx1",
    PhoneNumber : "+81電話番号",
    MessageAttributes : {
        'AWS.SNS.SMS.SenderID': {
        'DataType': 'String',
        'StringValue': 'MJELD'
        }
    }
})
Promise.all([aTest]).then((athreadList) => {
    athreadList.forEach(aVal => {
        console.log(aVal)
    })
})

exports.handler = async (event) => {}に実装しているのはlambdaでもテストできるように書いています。eventオブジェクトの中のMessageが本文で、PhoneNumberに+81のつく電話番号を設定します。