こんにちは。テックラボの佐々木です。主にバックエンドを担当しています。
フォースタートアップスは社外に公開している「STARTUP DB」の他にも複数のWebサービスを運用しています。ほぼ全てのサービスで認証機能を実装していますが、いくつかのサービスでは「Auth0」と呼ばれる認証機能構築のためのSaaSを利用しています。
この記事ではAuth0についてあまり知らない人向けに、Auth0を使って実現できることと弊社における実際の利用例を紹介します。
Auth0とは
Auth0は認証のトータルソリューションを提供するSaaSで、言語やフレームワークを問わずWebサービスやネイティブアプリに認証・認可の機能を実装できます。簡単なログイン認証機能であれば既存のアプリケーションに数行のコードを追加するだけで実装できます。
利用してみて感じたAuth0のメリットは以下の3つです。
複数サービスで同じ認証基盤を利用できる
言語やフレームワークによらないため、使い方を理解すれば他の言語・フレームワークを利用したサービスにも容易に横展開することができます。例えばフォースタートアップスではRubyで書かれたWebサービスで初めてAuth0を利用したのですが、そのタイミングで概念や使い方を理解できていたので、その後PythonやNode.jsを利用したサービスへの導入も素早く行えました。
また、Auth0はシングルサインオンや二段階認証といった認証に関わる様々な機能を実現できます。そのため機能ごとに別のライブラリやSaaSを利用する必要はなく、運用するサービス全てでAuth0を利用していれば、認証関連にかかる学習・実装コストを大幅に削ることができます。
素早く容易に実装ができる
単純なログイン認証機能であればAuth0のWebコンソールでの設定と、アプリケーションへの数行のコード追加だけで実装できます。
例えばJavaScriptだと以下のコード追加のみです。
document
.getElementById('login')
.addEventListener('click', async () => {
await auth0.loginWithRedirect();
});
Auth0: Secure access for everyone. But not just anyone.
https://auth0.com/jp/
その他にもGoogleやFacebookなどのソーシャルアカウント認証を利用するかどうかの設定や、アクセスコントロールの条件もWebコンソール上でできるため、コードに修正を加えることなく素早く直感的に実装ができます。実際にパスワード認証からGoogleアカウント認証への変更作業も、1分とかからずに対応できました。
認証関連の機能を容易に実装できるため、エンジニアはサービスのコア機能の開発に集中することができます。
多くの機能を無料で利用できる
Auth0は月間7000アクティブユーザーまでは多くの機能を無料で利用することができます。コンシューマー向けのサービスであれば無料で使うのは難しいかもしれませんが、エンタープライズ向けのサービスであれば初めのうちは十分に補える数だと思います。
認証は実装が難しい割にはユーザーにとって価値が見えづらい機能なので、MVPの段階ではAuth0を利用し、マネタイズできそうということがわかってからAuth0に課金するか別の方法で認証を実装するかを検討しても良いかもしれません。
Auth0を使って実現できること
具体的な利用例を紹介する前にAuth0で実現できることを紹介します。
ユニバーサルログイン
ユニバーサルログインとはセキュアなログイン認証画面を実現するための仕組みです。
ユニバーサルログインを利用するとログイン時にAuth0ドメインのログイン画面にリダイレクトされます。ログインと認証が同じドメインで行われドメイン間で認証情報が移動しないため、セキュリティが向上しフィッシング攻撃や中間者攻撃を防ぐことができます。
また、ログイン画面のUI/UXがデフォルトで用意されているため、UI/UXを一から構築する必要はありません。ユニバーサルログイン用に若干のコード追加は必要ですが、一度追加してしまえばその後はWebコンソールからログインページの多少のUI/UXを変更することができます。
M2M認証
アプリケーションから呼ばれるパブリックなAPIを作る際には、そのAPIに認証の仕組みを持たせる必要があることが多いです。
アプリケーションからリクエストを受けてAPIの認証トークンをアプリケーションに返す認証サーバーとしてAuth0を利用でき、セキュアなAPIを作成することができます。
以下の図の1、2のフローがM2M認証です。
機器間(M2M)認証を使用する
https://auth0.com/blog/jp-using-m2m-authorization/
シングルサインオン
シングルサインオンによってログインの回数が減るためUXの向上が期待できるだけでなく、ユーザーのパスワード管理の負担を減らすことでセキュリティリスクを削減できます。
フェデレーション方式でシングルサインオンを実現しており、未ログインのサービスへのログイン時にAuth0が提供するシングルサインオンサーバーにリダイレクトさせてCookie情報をチェックすることで、サービスの認証をすることなくログインできます。
How to Implement Single Sign On
https://auth0.com/learn/how-to-implement-single-sign-on/
自前のサービス同士のシングルサインオン連携だけでなく、Zoom、Slack、Office365等の17のサービス(2020/07/29時点)とも連携させることが可能です。
二段階認証
二段階認証の追加やどのような認証方式を利用するかの切り替えもWebコンソールから容易に実施できます。
認証方式はいずれも認証コードを入力するタイプで、SMS、メール、もしくはGoogle Authenticator等を利用したワンタイムパスワードを選択することができます。
不正ログイン検知
ブルートフォースアタックの検知、ブロック、通知をすることができます。
また、Auth0は漏洩済みのログイン情報を保持しており、それらのログイン情報を使用したログインについても検知、ブロック、通知することができます。
ユーザー管理
誰がいつログインしたかを確認することができ、ユーザーのブロックや削除等も行うことができます。
また、ユーザーに自前のロールを割り当て、アプリケーション側でそのロールを利用した認可を実施することが可能です。
パスワードレス認証
パスワード認証だけでなくGoogleやFacebookなどのソーシャルアカウント認証にも対応しています。2020/07/29時点では以下のようなメジャーなソーシャルアカウント認証を含めた34種類のサービスに対応しています。
認証時追加処理
認証処理の際にコールバック処理として、以下のようなアクセスコントロールやWebhook等を実行します。
- メールアドレスのドメインが指定したものと異なる場合にはログイン失敗させる
- 指定したIPアドレスのホワイトリストと異なるIPアドレスからのログインの場合にはログイン失敗させる
- ログインしたユーザーの情報をSlackに通知する
フォースタートアップスでのAuth0の利用シーン
フォースタートアップスでのAuth0の利用シーンとして、ユニバーサルログインを利用したログイン機能とM2M認証を利用したAPI認証の実装方法や留意点を紹介します。
ユニバーサルログインを利用したログイン機能
自社用に運用している採用管理ツールへのログイン機能、データ分析ツールとして利用しているKibanaへのログイン機能を実装するためにユニバーサルログインを利用しています。
採用管理ツールのログイン画面は以下のようになっています。フォースタートアップスドメインのGoogleアカウント認証のみを許可しているため、ログイン画面としては見た目は物足りないですが驚くほど簡単に実装できます。
実装の流れとしては以下の通りです。紛らわしいのですがAuth0にはApplicationという概念があり、OAuthクライアントのことを表します。以下に出てくるApplicationとは作成した採用管理ツールのことではなくAuth0のApplicationという概念のことです。
- Auth0のWebコンソールにてApplicationを作成する
- 上記のApplicationに、ログイン処理後に遷移する採用管理ツールのコールバックURLを設定する
- ログイン認証を付与する採用管理ツール側に、Auth0ログインページへの遷移処理とログイン後の処理を追加する
細かい手順については以下の通りです。この例はRuby on Railsの例ですが、選択した言語やフレームワークに応じた実装方法が丁寧に記述されています。
Auth0導入の前はRuby on Railsの認証ライブラリ「devise」を利用してログイン認証を行なっていました。
deviseには「current_user」「authenticate_user!」といった便利なヘルパーメソッドがあります。これらのメソッドをアプリケーション側でそのまま利用するために以下のモジュールを作成することで、既存コードへの影響を最小限にすることができました。
module Auth0Helper
private
def user_signed_in?
session[:userinfo].present?
end
def authenticate_user!
if user_signed_in?
@current_user = User.from_omniauth(session[:userinfo]) # from_omniauthはuserを特定するロジック
else
redirect_to login_path
end
end
def current_user
@current_user
end
end
M2M認証を利用したAPI認証
フォースタートアップスでは、Googleドライブ上のPDFをテキストに変換する処理を、AWSのAPI GatewayとLambdaを利用して構築しています。
PDFをパースする処理をAWS Lambdaで実装し、そのLambdaを呼び出すためのAPI GatewayのオーソライザーとしてAuth0を利用しています。
実装の流れとしては以下の通りです。
- Auth0のWebコンソールにてAPI(と呼ばれるAuth0認証するためのエンドポイント)を作成する。このAPIを利用することで、認証トークン(クライアントIDとクライアントシークレット)を利用してAuth0で認証可能となる
- クライアント側にて認証トークン取得処理とPDFパースAPIを呼び出す処理を記述する
- AWS Lambdaの呼び出し元としてAPI Gatewayを用意し、APIのオーソライザーとしてAuth0を指定する
細かい手順については以下の通りです。
利用するAmazon API Gatewayの種類として「金額は安いが機能が制限されるHTTP API」「金額は高くなるが高機能のREST API」の2つの選択肢がありましたが、Auth0がJWT オーソライザーに対応していたため特に制限を意識することなくHTTP APIを利用することができました。
現在動いている新規事業においてもこのAPI認証の仕組みを利用していますが、類似のアーキテクチャーで認証機能を実装できているため短時間で開発が進んでいます。
おわりに
Auth0を使って実現できることとフォースタートアップスにおける実際の利用例を紹介しました。
認証に関する様々な機能を容易に実装できることがAuth0の優れた点で、認証という技術的に難易度が高い処理をAuth0に任せることでエンジニアはサービスのコア機能の開発に集中できます。
活用しきれていない機能がまだまだあるので、今後も知見を溜めて社内外に情報共有できればと思います。