背景
AWS Amplify で作成するアプリにLINEログインを組み込み、ボットリンク機能(LINEログイン時に公式アカウントを友だちに追加する機能)を有効にしようと思ったのですがすんなりと行きませんでした。
ウェブアプリにLINEログインを組み込む | LINE Developers
LINEログインしたときにLINE公式アカウントを友だち追加する(ボットリンク) | LINE Developers
調査したところ、Cognito側でLINEの認可URLにパラメータを追加することができないようでした。詳しくは下記の記事を御覧ください。
Amazon CognitoではLINEログインのボットリンク機能は…使えません!
この記事は、API Gateway と Lambda を利用して上記を解決する方法を記載します。
解決方法
さっそく解決方法についてです。方法としては、
- Cognito の認可URLにAPI Gateway を設定
- API Gateway からLambda を呼び出し
- Lambda から
bot_prompt=aggressive
のクエリパラメータをつけて、LINEの認可URLにリクエスト - LINEの認可URLからのレスポンスをそのまま返す
となります。1, 2 については他の記事でも説明があるのでここでは省かせていただきます。
3, 4 について、今回はGolang を使用して下記のように実装しました。注意点としては、LINEの認可URLからは 302のリダイレクトが返ってくるので、それを処理せずにクライアント側に返送するようにします。また、基本的にヘッダやボディはコピーして利用するのですが、Host
のみ宛先によって変える必要があるので、そこだけは書き換えるようにします。
package main
import (
"log"
"net/http"
"strings"
"net/url"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"io/ioutil"
)
func handler(request events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) {
url := url.URL{
Scheme: "https",
Host: "access.line.me",
Path: "oauth2/v2.1/authorize",
// Query Paramter に bot_prompt を追加
RawQuery: request.RawQueryString + "&bot_prompt=aggressive",
}
client := &http.Client{}
// default でリダイレクトしてしまうので、無効化
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}
req, err := http.NewRequest(request.RequestContext.HTTP.Method, url.String(), nil)
if err != nil {
log.Fatal(err.Error())
}
// ヘッダをコピー(Host のみ書き換える)
for k, v := range request.Headers {
req.Header.Add(k, v)
}
req.Header.Set("Host", url.Host)
resp, err := client.Do(req)
if err != nil {
log.Fatal(err.Error())
}
defer resp.Body.Close()
byteArray, _ := ioutil.ReadAll(resp.Body)
// ヘッダとボディをコピーして返送
header := map[string]string{}
for k, v := range resp.Header {
if k!= "Host" {
header[k] = strings.Join(v, ",")
}
}
return events.APIGatewayV2HTTPResponse{
StatusCode: resp.StatusCode,
Headers: header,
Body: string(byteArray),
}, nil
}
func main() {
lambda.Start(handler)
}
ボツ案
APIGateway の機能で他のURLにパラメータを追加/変更/削除した上でリクエストを送信する機能があったのですが、こちらはうまく動作しませんでした(設定は下記の画像参照)。Cognitoから認可URLへのリクエストにはトークンなどの複雑なパラメータが含まれているので、それが原因かと考えています。トークンを含まないようなURLであれば、きちんと追加されていたので...残念...。