マツコの知らない LINE ログインの世界
Ubie プロダクトプラットフォーム所属の nerocrux です。今回は Ubie において、 LINE ログイン
を成功させるために工夫したことをいくつか紹介したいと思います。
面白いこともすごいこともやってないし、対象読者もよくわかりませんが、興味があったら読んでみてください。
はじめに
症状検索エンジン「ユビー」について
Ubie では、症状検索エンジン「ユビー」(以下、ユビー
と呼ぶ)という一般ユーザー向けのサービスを展開しています。ユーザーが簡単な質問を回答することで、関連する病名や、適切な受診先情報を得ることができるサービスとなっています。
ユビーは Web ブラウザ経由で利用されることが多いですが、iOS / Android のネイティブアプリも提供しています。
ユーザーがユビーを利用する際に、ユビーのアカウントを作成することで、一貫性のある問診・受診・受診後のフォローアップ体験を得られます。ユビーとしても、より品質の高いサービスをユーザーに提供するため、ユーザーにユビーアカウントを作成していただくことを期待しています。
ユビーアカウントを作成する方法としては、ユーザー自身のメールアドレスを利用する、もしくは Google / Apple / LINE といったソーシャルアカウントを利用する方法があります。
LINE ログインについて
ユビーにおいては、ユーザー認証時に一つの選択肢として LINE ログイン
を提供しています。LINE ログイン とは、LINE ヤフー社が提供する、いわゆる ソーシャルログイン
のサービスです。
LINE ログイン機能をユビーに組み込むことで、LINE アカウントを所持するユーザーは、LINE を指示して、LINE アカウントの一意的識別子が含まれるトークンをユビーに渡すことで、ユビーアカウントを新規作成できるようになります。
また、このプロセスの中で、ユビーアカウントを作成する際に必要な情報を自分自身でユビーのウェブサイト上に入力する必要がなく、LINE アカウントに紐づく同等な情報を LINE から取得する必要最小限の権限をユビーに付与することで、ユビーアカウントを手間なしでスムーズに作成できます。
LINE というサービスは、日本においては普及率が極めて高いチャット/SNSアプリで、日本人の約84%が利用しているといわれています。日本で生活するなら LINE は欠かせない存在で、多くの人は自分のスマホに LINE アプリをインストールして認証済みの状態にしています。そのため、日本においては LINE ログインをサービスに導入することで、スムーズな認証体験をサービス利用者に提供することが期待できます。
Ubie はまだ成長中であり、一時的にユビーを利用するユーザーを「アカウント作成済み」のユーザーに転換して、継続的な体験をユーザーに提供することで価値を生み出す必要があります。このプロセスの中で、ユーザー層の厚い LINE を活用してより多くのユーザーを獲得することが重要です。
ソーシャルログインの基本
LINE ログインを含めて、ソーシャルログインを安全に実現するには、OpenID Connect というプロトコルがよく利用されます。
OpenID Connect の具体的な仕組みについては一言二言では説明できません。また詳しく説明する記事がたくさんありますので、本記事では割愛します。OpenID Connect を利用してソーシャルログインを実装する際によく実装される流れは、公式仕様書から以下の概要のみ抜粋させていただきます。
OpenID Connect プロトコルは、 おおまかに言って以下のステップに従う.
1. RP (Client) が OpenID Provider (OP) にリクエストを送る.
2. OP は End-User を認証し, 認可を受ける.
3. OP は ID Token および (通常は) Access Token を返す.
4. RP は Access Token を添えて UserInfo Endpoint にリクエストを送る.
5. UserInfo Endpoint は End-User の Claim を返す.
これら一連のステップを以下に図示する.
+--------+ +--------+
| | | |
| |---------(1) AuthN Request-------->| |
| | | |
| | +--------+ | |
| | | | | |
| | | End- |<--(2) AuthN & AuthZ-->| |
| | | User | | |
| RP | | | | OP |
| | +--------+ | |
| | | |
| |<--------(3) AuthN Response--------| |
| | | |
| |---------(4) UserInfo Request----->| |
| | | |
| |<--------(5) UserInfo Response-----| |
| | | |
+--------+ +--------+
Ubie の認証基盤について
Ubie では症状検索エンジン「ユビー」を含め、JP / US において一般ユーザー向けの複数のサービスを開発運用しています。各サービスに一般ユーザー向けの認証機能を提供する必要がありますが、各サービスが各自で実装すると、開発負荷が高く、セキュリティ上の不具合が発生する可能性もあります。また、外部からの監査に対する対応などの負荷も高いと考えられます。そのため、実際にユーザー認証を行う機能は Orthrus と呼ばれる認証基盤に集約して開発しています。
社内の各ユーザー向けのサービスでは RP(Relying Party)として、OpenID Connect に基づき OP 役の Orthrus とやり取りして、認証に必要な情報(ID Token)を取得します。Orthrus では、独自で実装している Email OTP / SMS OTP 認証に加え、ソーシャルログインの機能も提供しており、各サービスがソーシャルログインを利用してユーザー認証を実施する場合、今度 Orthrus が RP になり、Google, Apple, LINE など各外部 ID プロバイダーとやり取りします。
上記構成を踏まえて、ユーザーがユビー上で LINE ログインを使ってアカウントを新規登録する場合、全体的な流れは下図に示した通りになります。
LINE ログインの失敗ポイントと対策
それでは、本題に入りたいと思います。
ご存知の通り、LINE は基本的にネイティブアプリを通して利用するサービスで、Web ブラウザー上に LINE 側の認証済みセッションの存在があまり期待できません。 Web ブラウザ上で LINE ログインを実施すると、LINE 側で LINE ユーザー認証を明示的に実施する必要があり、LINE の ID パスワードを入力する画面が出てきます。せっかくユーザー端末上に認証済みの LINE アプリがインストールされているのに、再度 ID パスワード入力しなければならなくなると、ユーザー体験が悪くなってしまいます。
また、LINE は基本的にアプリに一回ログインしていれば、機種変更するまでにほとんど再認証が発生しません。パスワードマネージャーが全てのユーザーに普及しているとは言えない現在では、LINE へログインする行為を日常的に行っていないユーザーにとって、LINE の ID パスワードが聞かれたときに、ストレスフリーで入力できるケースが少ないと考えます。
このような背景もあり、LINE ログインの体験を大きく改善してくれるのは LINE 自動ログイン という機能です。一定の条件を満たした[1]場合、ユーザーが LINE ログインを実施する際、Web ブラウザ上で認証が発生することなく、LINE アプリに遷移して OP 側での認証が自動的に実施される形になります。
LINE 社公式ドキュメントより引用
LINE ログインを利用する際には、いかにブラウザ上で LINE の ID パスワードの入力を回避し、「LINE 自動ログイン」を発動させた上、ユビー側で正しく認証プロセスを完了させるかが重要です。
ただし、ほかのプロバイダと違って、認証が Web ブラウザ上で完結するのではなく、アプリ間の遷移が発生するため、認証プロセスが正しく完結することを阻害する要素が出てきます。何かしらの理由で LINE アプリへの遷移が発生しないこともあります。実際にLINEアプリに遷移したあとに遷移元のアプリに戻れず、認証が継続できなくなるケースもありました。LINE ログインを導入する際にこのような問題点を克服して、いかに LINE 自動ログインを順調に終わらせるかがチャレンジングポイントだと考えます。
それでは、弊社で実際遭遇した問題点とそれを克服するための対策をいくつか紹介したいと思います。
1. 認証開始時の User Agent に戻れない問題
LINE 自動ログインでは LINE アプリへ遷移してしまうため、LINE アプリから認証開始時のブラウザやアプリに戻れない、認証が失敗してしまうケースがいくつか存在します。
a. 〇〇アプリの In App Browser の場合
弊社ではいくつかの媒体に Web 広告を出稿しています。例えば X のタイムライン上に、ユビーの広告が出てくることがあって、ユーザーが広告をタップしたら、X の In App Browser が開かれ、https://ubie.app が開かれます。
また、Google の検索アプリなど、ネイティブアプリを利用して病状を検索したら、ユビーの結果がヒットし、検索アプリ内のブラウザでユビーが開かれるケースもあります。
こういった In App Browser 内でユーザーが LINE ログインで認証を始めると、自動ログインで LINE アプリが起動されますが、元のアプリに戻ることができず、iOS の場合だと Safari に遷移し新しいタブが開かれる挙動になります。
Safari アプリと X などの In App Browser の間に Cookie が共有されてない[2]ため、Safari アプリから認証開始時のセッションを取れません。CSRF を防ぐ観点では、認証開始時のブラウザ内のセッションと、コールバック時ブラウザ内のセッションが同じものであることを確認するため、ブラウザが変わることで認証が失敗で終わります。
また、ユビー側としては、In App Browser と Safari アプリの区別がつきません。In App Browser だからこうする、というような対応はできません。
このようなケースに対しては、以下の対策を取っています。
LINE アプリから戻ってきたとき、Safari アプリへ遷移することは回避できませんが、コールバック時セッションがなく失敗した場合、認証基盤の Orthrus はブラウザが変わったと判断し、ユビーに browser changed エラーを返します。
ユビーとしては、browser changed エラーを受け取ったあとに、Safari 上でユーザーがすでに認証済みでなければ、なにかしらのエラー画面やログイン画面をユーザー表示する代わりに、ユーザーが LINE ログインボタンを押した際と同様な処理(セッションを新規作成し、認証リクエストを送信する)を自動的に最初から実行して、認証リクエストを Orthrus に送り直します。そうすると LINE 自動ログインが再度発動され、今度はブラウザの変更がないため、認証が成功します。
ユーザーとしては、特に変わった操作をしてなかったため、ブラウザが変わりエラーが発生した場合、エラー画面でユーザーに何が起きたかをわかりやすく説明することが難しいです。In App Browser の中でユーザーが LINE ログインを行う
意思を示したため、ブラウザが変わった際に再度ユーザーに最初からログインの操作をしてもらう必要がなく、ユーザーが In App Browser 内で選択した認証手段でユビーにログイン成功させるべきだと考えます。
最終的にブラウザが変わり(InApp Browser → Safari)、アプリ間の遷移も何度か起きますが、ユーザー操作は基本的に発生しないため、スムーズなユーザー体験が実現出来ると考えます。
b. Yahoo アプリの場合
Yahoo アプリ内でユーザーがユビーを検索すると、アプリ内 Webview (InApp Browser ではない)が開かれ、その中でユビーを開いて LINE ログインを実施するケースがかなり多いです。
Yahoo アプリ内 Webview 上で LINE 自動ログインを実行すると、LINE アプリに遷移したあとに、Yahoo アプリに戻ることができます[3]。これはかなり良いユーザー体験ですし、弊社 Yahoo 検索からのユーザーが多いため、助かってます。
ただし、Yahoo アプリからの LINE 自動ログインを成功させるため、LINE に送る認証リクエストに PKCE 対応が必須となります。PKCE に対応してなければ自動ログインも Yahoo アプリへの遷移も出来なかったはずですので注意が必要です。
参考: https://developers.line.biz/ja/docs/line-login/integrate-pkce/
c. Google 検索アプリの場合
Yahoo アプリと似たように Google 検索アプリ(iOS のみ)からユビーへのアクセスもかなり多いです。しかし Yahoo アプリと違って、LINE 自動ログインを実施したあとに、Google 検索アプリへ戻ることができず、Safari アプリに遷移する形になります。
その場合、a と同様にユビーが認証リクエストを送り直すことで、Safari アプリ上でユーザー認証を成功させられます。
2. Private Browse モードについて
iOS / MacOS Safari にプライベートブラウズモード、Android Chrome に Incognito タブと呼ばれる、プライベートブラウジングの仕組みが用意されています。このモードを利用する場合、LINE 自動ログインは成功しません。
理由としては、LINE アプリに遷移してブラウザに戻ったあとに、プライベートブラウズモードの場合、新しいタブが開いてしまいます。プライベートタブ間では、Cookie が共有されないため、ブラウザが変わったときと同じ挙動となり、認証が成功しません。
このときの対策としては、LINE ログイン時に、LINE に対して 自動ログインを無効にする
ことを明示的に指定します[4]。
ユーザーがプライベートモードを利用しているかどうかは Javascript によって検知できます[5]。ユビーはプライベートモードを検知したら、LINE ログイン実行時に Orthrus に disable_auto_login=true のフラグを送ります。そうすると Orthrus が LINE に送るリクエストの中でも disable_auto_login=true を送ることで、LINE 自動ログインを無効にし、LINE アプリへの遷移を止めます。
こうすることで、LINE ID パスワード入力の画面が表示され、ユーザー入力が必要となりますが、正しく入力すればログイン自体は成功します。
3. ネイティブアプリについて
ユビーのネイティブアプリ上の認証に関しては、iOS では ASWebAuthenticationSession 内、Android では Chrome Custom Tabs 内で実施します。
しかし ASWebAuthenticationSession 内では Orthrus から LINE にリダイレクトする際に、LINE 自動ログイン(=LINE アプリへの遷移)がほとんど発動できませんでした。
ユーザーがユビーの UI 上で LINE ログインボタンをタップすると、ブラウザ上で Orthrus → LINE の順でリダイレクトします。Orthrus → LINE への遷移(OIDC の認証リクエスト送信)は、ユーザー操作がなく、自動的にリダイレクトし、LINE アプリが起動されることが期待されますが、iOS ネイティブアプリ(ASWebAuthenticationSession 内)の場合のみ、おそらく OS の制約で Universal Links がアプリにフックされず、LINE アプリへ遷移しない現象が発生します[6]。
解決策としては、Orthrus が認証リクエストを受信したあとに、そのままブラウザ上で LINE へリダイレクトするせず、意図的に 1 ページ挟み、ボタンをユーザーにタップさせます。そうすることで、LINE 自動ログインが正しく動作するようになります。
画面とユーザーアクションが増えるのは怖いですが、実際全体的なUX が良くなったため、このパターンの認証完走率が大幅に改善されました。
また、LINE アプリへ遷移したあとに、ユビーアプリに戻らなければなりません。LINE アプリの戻り先(OIDC の redirect_uri)は認証基盤の Orthrus であるため、Orthrus のドメインにユビーアプリを起動するための Universal Links (AASA) や AppLinks を設置する必要があります。
これらのリンクを設置する際に、Web 版のことを考慮する必要があります。Web から LINE ログインして Orthrus へコールバックする際、ユビーアプリを起動してはいけません。そのため、Orthrus 側で LINE のコールバック先(Redirect URI)はネイティブ用と Web 用のものをそれぞれ用意し、ネイティブ用のエンドポイントのみを AASA に登録することで、ネイティブからのコールバックのみユビーアプリを起動するようにしています。
補足 1
ネイティブアプリに LINE ログインを組み込む際に、LINE SDK を導入することで、 LINE アプリに遷移 → 元アプリに戻すことが可能になります。
しかしユビーの場合では、LINE とやりとりするはアプリではなく、Orthrus になるため、ネイティブアプリに LINE SDK の導入が困難でした。
ユビーのように外部 ID プロバイダと一元的にやり取りするサービスを経由しない場合、LINE ログインの実装は LINE SDK を利用すると良いと考えます。
補足 2
iOS の制約で、作成されている ASWebAuthenticationSession の中に、更に新しい URL に遷移させるすべがありません。その関係で、ASWebAuthenticationSession で LINE 自動ログインを有効にする場合、ASWebAuthenticationSession を複数回作る必要があります。
まず、ユビーアプリから Orthrus を呼び出す際に、ASWebAuthenticationSession を新規作成します。
LINE 自動ログイン実施後、LINE アプリ → ユビーアプリへと戻る際に、ASWebAuthenticationSession の中で OIDC のプロトコルに従い、Redirect URI にリダイレクトする必要があります。その際に、既存の ASWebAuthenticationSession を close してから、新たに ASWebAuthenticationSession を作成し Orthrus の Redirect URI に遷移させなければなりませんでした。
しかしこの方法だと ASWebAuthenticationSession を開く際に「〇〇がサインインのために〇〇を使用しようとしています。続けますか?」のようなダイアログが表示され、ユーザーアクションが必要となってしまい、UX 的によくありません。
この Bad UX を解消すべく、いくつかの案を検討しました。
例えば ASWebAuthenticationSession を利用せず、LINE ログインの場合には外部 Safari で Orthrus へ送信する認証リクエストを送る案がありました。そうするとユビーアプリ → Safari → LINE アプリ → Safari → ユビーアプリの順に遷移し、ユーザー操作なしで認証成功になります。
しかし Safari アプリがプライベートブラウザモードになっている場合、前述の通り LINE アプリ → Safari に戻る時認証が必ず失敗になります。プライベートブラウザを利用するユーザーが一定数存在するので、この案は見送りました。
このあたりは今後の改善ポイントになっています。
ID パスワード入力が避けられない場合
LINE ログインのみならず、ソーシャルログインによる新規登録時に、外部プロバイダ側でユーザーがログインしていない場合、ID パスワードを入力するなどの操作が発生し、ユーザーが離脱する可能性が高くなります。
ID パスワード入力を回避するため、ユビーでは UserAgent の種類を見て、ユーザーに見せる外部プロバイダーのボタンを選別しています。高い確率で ID パスワード入力が求められる場合、ログインボタンを「その他の方法でログイン」 メニューの中に隠し、ID パスワード入力する必要がない可能性の高いプロバイダーのみをユーザーに提示するようにしています。
具体的な対照表は以下の様になります。
iOS Safari | iOS Safari Private | iOS Google App | iOS Yahoo App | Android Chrome | Android Chrome Private | Android Yahoo App | PC | PC Private | |
---|---|---|---|---|---|---|---|---|---|
LINE | ◯ | △ | ◯ | ◯ | ◯ | △ | ◯ | △ | △ |
◯ | △ | ◯ | ✘ | ◯ | △ | ✘ | ◯ | △ | |
Apple | ◯ | ◯ | ◯ | ◯ | △ | △ | △ | △ | △ |
説明 | 対応 | |
---|---|---|
◯ | 高い確率で ID パスワード入力など明示的な認証が発生しない Good UX。 | ボタンを表示 |
△ | 高い確率で or 確実に ID パスワード入力など明示的な認証が発生する。人によって Bad UX になる。ただし動くは動く。 | ボタンを「その他の方法でログイン」に隠し、タップしたら表示される |
✘ | 確実に動かない、認証できない。 | ボタンを表示しない |
例えば、iOS において Sign in with Apple を実施する、もしくは Android において Sign in with Google の場合、OS レベルで Apple / Google アカウントに認証済みの状態になっているため、ソーシャルログイン時のユーザー体験がよく、積極的にユーザーに利用してもらいたいです。
逆に Android において、Sign in with Apple を実施するとほぼ確実に Apple ID のメールアドレスとパスワード + OTP コードを入力しなければならないので、ユーザーが離脱しやすいです(そもそも Android ユーザーが Sign in with Apple を選択することほぼないですが)。
また、どのプロバイダーでも、必ずユーザー入力が発生しそうな場合、メールアドレス OTP による新規登録の選択肢をユーザーに提示するようにしています。
iOS Safari | iOS Safari Private | iOS Google App | iOS Yahoo App | Android Chrome | Android Chrome Private | Android Yahoo App | PC | PC Private | |
---|---|---|---|---|---|---|---|---|---|
Email OTP | △ | ◯ | △ | △ | △ | ◯ | △ | ◯ | ◯ |
もちろんこれは強制ではなく、最終的にユーザーが自分の意思で認証の手段を選択することが可能になっています。
ちなみに LINE ログインとは無関係ですが、iOS /Android Yahoo アプリにおいて、Google ログインを表示しないようにしています。これは Google のポリシーによって WKWebView が禁止され、Google ログインが絶対に成功できない(disallowed_useragent が発生する)ためです[7]。
最後に
ユーザー認証は UI / UX 的にシンプルに見えますが、実はそのフローがかなり長く、ユーザーがどのステップで離脱したか、なぜ離脱したか(UX が悪い、エラーが起きた、etc)を理解することが重要です。
Ubie はデータの会社で、dbt / lightdash など分析ツールをデータ基盤チームが整備してくれてます。そのおかげで、ログを仕込めば、各ステップにおいてユーザーの到達率を OS / UserAgent ごとに集計することができ、認証失敗もしくは離脱の原因分析に役に立ちます。
将来的にパスキー及びパスワードマネージャーの普及によって、このようなチューニングがいらなくなるかもしれませんが、今の段階では(特に LINE 自動ログインのようなやや特殊なケースにおいては)ソーシャルログインの成功率を上げるために引き続き頑張る必要がありそうと感じてます。
-
公式ドキュメントでは一定の条件とはなにかについて特に明言していませんが、「スマホ版 LINE アプリがインストールされ、ログイン済みの状態になっている」と理解しています。 ↩︎
-
Android の場合、CustomTabs と Chrome アプリの間に Cookie が共有されるので、この問題が起きません。 ↩︎
-
グループ会社ならではの施策? ↩︎
-
参考:https://developers.line.biz/ja/docs/line-login/how-to-handle-auto-login-failure/ ↩︎
-
detecticongnitojs などのライブラリが存在します。 ↩︎
-
iOS Safari や Android Native App では問題なく遷移する。 ↩︎
-
参考: https://developers.google.com/identity/protocols/oauth2/native-app?hl=ja#authorization-errors-disallowed-useragent ↩︎
Discussion