岩本隆史の日記帳(アーカイブ)

はてなダイアリーのサービス終了をうけて移行したものです。更新はしません。

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標準の認証処理でいけるのではないかと思っています。

こんなイメージです。

  1. クライアント作成者はWebアプリ上でクライアント情報を登録する。その際、Webアプリはクライアントキーを発行する
  2. ユーザはWebアプリ上でアクセス許可クライアントを登録する(委譲)。*1その際、Webアプリはユーザ×クライアント単位のトークンを発行する。
  3. ユーザはクライアント上でトークンを入力する
  4. クライアントはWebサービスにアクセスする際の認証情報としてクライアントキー+トークンを使う

構想中なので、穴があるかもしれません。

なお、250ページ(私の持っているのは初版第2刷)に、Digest認証のオプションとして「qop=authint」と書かれていますが、これは「qop=auth-int」の誤記だと思います。

*1:機能ごとにread/write権限が設定できると望ましい