WebアプリとWebサービスは違うことにようやく気づいた
『RESTful Webサービス』の第3回読書会に参加するため、6〜8章を読み返しています。構想中のWebアプリの認証周りについて考えていたところで、読むのにちょうど良いタイミングでした。
まだ全部を読みきってはいませんが、「6.1.1 ユーザーアカウントはなぜリソースなのか」に「Webアプリケーションの設計は一般的なテーマであり、本書のテーマではない」とあるのを読み、衝撃を受けました。そうか! これはWebサービスのアーキテクチャを提案する本だったんだ!
ここしばらく私が悩んでいたのは、Webサービス向けに提案されているアーキテクチャ(ROA)をそのままWebアプリに適用しようとしていたせいだったんだと、ようやく気づいたわけです。
おかげで、WebアプリとWebサービスを分けて考えることができるようになり、下記の方針に至りました。
- WebアプリもできるだけROAベースにする。どうしようもないところはあっさり妥協
- ユーザ登録以外の処理は、セキュリティ上の問題がない限り、ROAベースのWebサービスとしてもWebアプリとしても公開する
- ユーザ登録処理は、Webサービスとしては公開しない。スパムユーザの登録を防ぐため(「7.3.2 ユーザコントローラ」のコラムを参照)
- WebアプリとWebサービスでは認証処理を別にする。WebアプリはCookieにセッションIDを保存。WebサービスはDigest認証(理想はBasic認証+SSLだが、コストと相談)
ちなみに、Webサービスクライアントにパスワードを渡さないための認証・認可方式として、最初はOAuthを考えたのですが、ユーザがクライアント作成者に権限を委譲する仕組みをWebアプリに実装すれば、Basic認証やDigest認証といったHTTP標準の認証処理でいけるのではないかと思っています。
こんなイメージです。
- クライアント作成者はWebアプリ上でクライアント情報を登録する。その際、Webアプリはクライアントキーを発行する
- ユーザはWebアプリ上でアクセス許可クライアントを登録する(委譲)。*1その際、Webアプリはユーザ×クライアント単位のトークンを発行する。
- ユーザはクライアント上でトークンを入力する
- クライアントはWebサービスにアクセスする際の認証情報としてクライアントキー+トークンを使う
構想中なので、穴があるかもしれません。
なお、250ページ(私の持っているのは初版第2刷)に、Digest認証のオプションとして「qop=authint」と書かれていますが、これは「qop=auth-int」の誤記だと思います。
*1:機能ごとにread/write権限が設定できると望ましい