認証機能を独自実装する代わりにIDaaSのREST APIを使うアプローチ

こんにちは、ritou です。

最近のあれこれでIDaaSと呼ばれる機能に注目が集まっているような気がしますが、どうしてもフロントエンドでの導入部分が目に付きます。 「新規サービスで使っていこう」ならまだしも「既存のを何とかしたい」みたいな場合にフロントエンドまでごっそり変えるのなんて腰が重くなって仕方ない感じでしょう。

そこで今回は、REST APIを用いた新規導入、移行というアプローチもあるのかなという話を書いておきます。

IDaaS の REST API

この辺りをみてみてはどうでしょう。

APIベースで登録/ログイン/パスワード変更など結構揃っている印象です。 Firebaseだとソーシャルログインも実現できそうですし、Auth0のはまだあんまりじっくりみてないですがMFAとかも書いてあります。 あとはCognitoなんかもAPIいっぱいありますよね。

導入方法

このようなREST APIでは

  • UIを自前で用意
  • 受け取った値をさばくバックエンドの処理をREST APIで実現

という感じになりますね。それこそDeviseでやってたところをこのREST APIを使うパターンです。 サービスの種類は違いますがAuthleteはこれで認可サーバーを作っていく形ですね。

SPAかどうかにもあまり依存せずに使えそうですし、フロントにIDaaSのSDKを入れてガッツリUIレベルまでIDaaSに従う実装よりも自然に導入できそうな気がします。 私自身、自前でいくつか認証機能、基盤の開発をやってきた中でまだガッツリこの方式で作り込んだことはないんですが、やるとしたらこのアプローチかなと考えています。

IDaaS導入における不安要素にIDaaSが落ちたらどうする問題があるかと思うんですが、例えばREST APIを用いて取得したユーザー情報を "外部サービスであるIDaaSからの認証結果" と捉えてセッション管理などを自前にする設計パターンもあるんじゃないかと。 万が一IDaaSが落ちてたとしてもエラーハンドリングというかConfig設定とかで一時的にIDaaSに流さないようにし、登録済みメールアドレスなどを用いて自前でリカバリーというか暫定的な認証機能を提供するような感じならそれほどリスクなくできそうかなー、いやでもやっぱめんどくせーなーなどと思いながら引き続き検討してみるつもりです。

IDaaSにとってそれを使うサービスはどんな役割なのかを意識しよう

例えばOpenID Connectでいうところで ”IDaaSがOP、利用サービスがClient" という立場であるように考えがちです。 今回紹介したREST APIを使うイメージとあっているでしょう。

しかし、フロントエンドのSDKなどを使う場合、セッション管理のあたりまでJSでできてしまいます。 IDaaSの責務でセッション管理までする場合、利用するサービスが行うべきことは「現在ログイン中のユーザーを把握してそれに対するリソースアクセスを提供する」ということになり、役割としては利用するサービスのSPAがClient、バックエンドサーバーがResource Serverとなります。

IDaaSを効果的に使っていくためにはこの辺りも意識して設計/実装を進める必要があるでしょう。

まとめ

  • REST API結構ある
  • フロントエンドをあまり使わずにバックエンドで導入していくアプローチもあるのではないか
  • 自分はClientを作るのかResource Serverだけにするのかというレベルの検討も必要そう

おまけ

Firebase AuthnのAPIに「OAuth認証情報でサインインする」というのがあります。

https://firebase.google.com/docs/reference/rest/auth#section-sign-in-with-oauth-credential

いわゆるソーシャルログインをAPIベースでやろうとするものですね。

過去にネイティブアプリとバックエンドサーバーをOAuth 2.0のClient/Serverとして作り込まれたプラットフォームに関わっていたときに、ネイティブアプリでのソーシャルログイン実装でこのような独自拡張を実装したことがあります。

メンテナになってるPerlのOAuth 2.0 Serverライブラリである OAuth::Lite2 にはその痕跡が残されています。やりたい放題でした。

Changes - metacpan.org

0.09 2014-07-22T07:36:43Z
    - rename grant_type to external_service
    - rename params for grant_type=external_service
 
0.08 2014-06-03T07:54:41Z
    - add support for new grant types
        - "urn:ietf:params:oauth:grant-type:federated-assertion" : obtain access_token from external service assertion

GrantTypeにソーシャルログイン用のものを作成して、例えばGoogleなどから受け取ったAT/RT/AuthzCode/IDTokenなどを送ってログインさせようというものです。 オレオレ拡張仕様のメモ:

social_login_bearer_profile_for_oauth2.md · GitHub

このように、APIベースでもソーシャルログインなど実装できるものはたくさんありますので、今回紹介したREST APIを使ったアプローチを検討してみてはいかがでしょうか。

ではまた!

f:id:ritou:20200819131651p:plain