Amazon S3 + LINE Messaging APIで画像テキストを出すときにはまったこと

概要

  • LINE Messaging APIで画像を送った時のセキュリティの話
  • そのときにはまったことのメモ

Messaging API

LINEのMessaging APIとはLINE Botを作るときなどに利用するサービスである。本サービスを利用して対象のLINEユーザのIDに対してメッセージを送ることができる。 メッセージにはプレインテキスト以外に画像や音声なども送ることができる。

Messaging APIリファレンス

  • 前提事項
    • LINE Messaging APIでユーザに送信する画像はHTTPSのURLを形式である必要がある。
    • ユーザのLINEが動いている端末から取得しに来るためIP制限等でセキュリティ担保は難しい

Messaging APIのはまりどころ

アクセストークンが切れたときのレスポンストラップ

アクセストークンが切れた=認可切れなのでHTTP403がかえってきてほしいがHTTP400がかえってくるためエラー切り分けに少し手間取った。 個人的にこれ、結構なトラップ。。。

HTTP400トラップ

URL誤りであろうがテキスト誤りであろうが大体のエラーがHTTP400でかえってくるためエラーレスポンスだけからではエラー箇所特定が難しい。

S3から画像取得

S3から画像を取得するためにS3のバケットポリシーをある程度公開することもできる。しかし、S3のバケットをパブリック公開にするのは避けたい。 そこで思いつくのが署名付きURLです。署名付きURLを使うことによって、時間制限をつけてアクセス可能とするURLを発行できます(時間制限付きのIAM Roleがつく)。

S3に格納した画像をLINE Messaging APIで取得する際、この方法を考えましたが今回ここでハマりました。

ハマりどころ

  1. S3の署名付きURLを発行すると約1000文字ちょいのURLが返却される。
  2. LINE Messaging APIの画像格納先URLの最大文字が1000文字。。。
  3. f:id:horsewin:20190519161353p:plain
  4. bitlyなどで短縮URLを発行してアクセスさせることを考える
  5. LINE Messaging APIの画像格納先URLがHTTPSである必要があるため無理。。。

解決策

単純にS3だけではどうしようもなかったです。解決のために取れる手段(パブリック公開を除く)は2つです。

  1. CloudFrontを用いてアクセスさせた際にリダイレクトで返す。
  2. DynamoDBに署名付きURLのクエリパラメータを確保させておき、CloudFrontを用いて短いURLでアクセスさせる。この際、Lambda@Edgeでリクエストをインタセプトし、DynamoDBに保管したクエリパラメータをひっつけて返す。

所感

最大文字数が1100文字とかならこんな苦労なかったのに。。。となりました。