0
Help us understand the problem. What are the problem?

posted at

AWS Cognito でLINEログインのボットリンク機能を使う

背景

AWS Amplify で作成するアプリにLINEログインを組み込み、ボットリンク機能(LINEログイン時に公式アカウントを友だちに追加する機能)を有効にしようと思ったのですがすんなりと行きませんでした。

ウェブアプリにLINEログインを組み込む | LINE Developers
LINEログインしたときにLINE公式アカウントを友だち追加する(ボットリンク) | LINE Developers

調査したところ、Cognito側でLINEの認可URLにパラメータを追加することができないようでした。詳しくは下記の記事を御覧ください。

Amazon CognitoではLINEログインのボットリンク機能は…使えません!

この記事は、API Gateway と Lambda を利用して上記を解決する方法を記載します。

解決方法

さっそく解決方法についてです。方法としては、

  1. Cognito の認可URLにAPI Gateway を設定
  2. API Gateway からLambda を呼び出し
  3. Lambda から bot_prompt=aggressive のクエリパラメータをつけて、LINEの認可URLにリクエスト
  4. 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であれば、きちんと追加されていたので...残念...。

AWS APIGateway のIntegration
AWS APIGateway のParameter Mapping

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
0
Help us understand the problem. What are the problem?