以前、Amplify Gen2にGoogleをIDプロバイダーとして追加したが、LINEログインの実装のため、同様にLINEをOIDCプロバイダーとして追加したのでメモ。
環境
@aws-amplify/backend v1.0.4, @aws-amplify/backend-cli (ampx) v1.2.1。
フロントエンドの実装にはReact + Next.jsを利用。
OIDCプロバイダー設定方法
前回と同様、公式ドキュメントを参考とした。
LINEログインの設定手順
LINE Developersコンソールでのチャネル作成
LINE Developersコンソールにて、「チャネルの種類」を「LINEログイン」にしたチャネルを作成し、チャネル基本設定タブより、チャネルIDおよびチャネルシークレットを確認しておく。
作成後、LINEログイン設定タブの「コールバックURL」に <Cognitoドメイン>/oauth2/idpresponse を設定する必要がある。今回は、GoogleをIDプロバイダーとして設定済みで、Cognitoドメインが発行済みのため、そのまま設定した。
また、チャネルのステータスがデフォルトでは「開発中」のため、このままではLINEログインできない。チャネルを公開するか、権限設定タブからメールアドレスでログインを行うLINEアカウントを追加しておく。
メールアドレスの取得権限の申請
以前の設定で、メールアドレスを必須とせざるを得なかったため、LINEへのサインアップ時にもメールアドレスを取得したい。
そのためには、メールアドレスの取得権限の申請が必要となる。
作成したチャネルを開き、チャネル基本設定タブの最下部、「メールアドレス取得権限」の「申請」ボタンをクリック。
メールアドレスの取り扱い、およびLINE User Data Policyへの遵守に関するチェックボックスがあるので、それぞれチェック。
続いて、「あなたのアプリでメールアドレスの取得/利用目的について、ユーザに通知、明示、および同意を取得している部分のスクリーンショットをアップロードしてください。」に、該当部分のスクリーンショットをアップロードする。
2つのチェックボックスのチェック、および画像のアップロードを行い、申請ボタンをクリックすると、ステータスが「申請済み」となる。即座にサインアップ時にメールアドレスの取得ができるようになったため、審査などは行っていない模様。
なお、この設定をしないと、サインアップ時に必須属性なしでエラーとなる。
/?error_description=attributes required: [email]&state=...&error=invalid_request
Amplifyのシークレット追加
確認しておいたチャネルIDおよびチャネルシークレットを、シークレットとして追加する。それぞれ LINE_CHANNEL_ID, LINE_CHANNEL_SECRET という名前で追加した。
サンドボックス環境では、以下のコマンドで設定。
npx ampx sandbox secret set LINE_CHANNEL_ID npx ampx sandbox secret set LINE_CHANNEL_SECRET
amplify/auth/resource.ts の設定
amplify/auth/resource.ts の defineAuth に渡すオブジェクトに、 loginWith.externalProviders.oidc を追加する。
issuerUrl には https://access.line.me を設定する。 scopes に指定できる値の組み合わせは、公式ドキュメントを参照。今回はメールアドレスが必要なので、 openid および email を指定する。
export const auth = defineAuth({ loginWith: { email: true, externalProviders: { google: { clientId: secret('GOOGLE_CLIENT_ID'), clientSecret: secret('GOOGLE_CLIENT_SECRET'), scopes: ['email'], }, // 以下追加 oidc: [ { name: 'LINE', clientId: secret('LINE_CHANNEL_ID'), clientSecret: secret('LINE_CHANNEL_SECRET'), issuerUrl: 'https://access.line.me', scopes: ['openid', 'email'], }, ], // 追加ここまで // 中略 }, }, })
ログイン画面の設定
フロントエンド側の変更だが、 @aws-amplify/ui-react の Authenticator を用いる場合、任意のOIDCプロバイダーは表示できない模様。 socialProviders プロパティは存在するが、 google や facebook など、プリセットの4種類しか指定できない。
以下のissueで機能要望が上がっているが、現状未対応。2021年11月オープンで特に動きがないので、対応は期待薄だろう。
上記issueより、以下のページにリンクあり。フッターをカスタムし、 import { signInWithRedirect } from 'aws-amplify/auth' を用いたボタンを追加している。
ということで、以下のようにLINEログインボタンを追加。
import { Authenticator } from '@aws-amplify/ui-react' import { signInWithRedirect } from 'aws-amplify/auth' const components = { SignIn: { Footer() { return ( <button onClick={async () => // プロバイダー名は `amplify/auth/resource.ts` の // `oidc.name` を設定 await signInWithRedirect({ provider: { custom: 'LINE' } }) } > LINE でログイン </button> ) }, }, } export default function Page() { return ( <Authenticator hideSignUp components={components} > {({ signOut, user }) => { // 中略 }} </Authenticator> ) }
Googleの場合と同様、事前のサインアップは不要。追加したボタンをクリックすると、LINEのログイン画面が開く。ログインすると初回は同意画面が開き、同意されればログイン成功。Cognitoに line_ を接頭語としたSubでユーザーが登録される。
振り返り
auth側での設定は簡単だが、UIを実装する必要があるのはやや面倒。
Google等、あらかじめ用意されているIDプロバイダーのボタンと同じ幅や高さのボタンが用意されていると嬉しいが、ないものねだりしても仕方がない。
また、LINEのログインボタンには、デザインガイドラインが存在する。
外部に公開する際には、このガイドラインに沿う必要があるので、後ほどUIを整える必要がある。
アイコンは以下で配布されているので、それを元にいじってみるか。