RESTful ユーザー登録, パスワードリカバリ

REST本があまり参考にならなかった罠。email や パスワード のような本人確認が必要なリソースを作成する、という点をどうするか?

まず登録。

  • POST /users
  • GET /users/{:id}/registration_prepared
  • GET /users/{:id}/registration_confirmation?key={temporary key}

こんな感じだろうか。で、パスワードリセット

  • POST /users/{:id}/new_password
  • GET /users/{:id}/new_password_prepared
  • GET /users/{:id}/new_passward_confirmation?key={temporary key}

。。うーん、RESTfulとは相性が悪いというか、この辺はコンピュータだけで済ませないために、「メールなどで確認する」という人的プロセスを経ているわけで*1。。

修正。よく考えたらpreparedは、あまり意味がないことにきがつく。HTTPの表現力で、送信されたことを機械的に表現する手段がないではないか? SMTPURIをふってというのも、現実的ではないし。結局、クライアント側は200が返されたときの次のアクションは、APIドキュメントによって確認して、しかるべき対応をする、というのが解か。

あと、GET *_confirmation が正しいかどうかはわからないが、メールクライアントからブラウザに対しては、URIは渡せるけど、HTTP Methodは渡せないので、仕方がない、といったところか。もちろん Rails なら _method=post とかすればいいんだろうけど。

RPC形式のWebサービスなら、あまり考えずに、準備用RPCと確定用RPCを用意すればいいんだろうけど。

*1:例えば、オンラインショップの決済には確認画面が必要、といった法律関係

[開発] RESTful

とりあえず、ここまでは完成。方針転換をして、db/migrate に記述したデータについては、すべて app/ 内で何らかのRESTfulなインターフェースを用意しておこうかと。今までは、components/system に押し込んでいましたが、どうもきれいじゃないと思ったので。

components/* に押し込んだウィジェットの取り扱うデータをRESTfulに提供する手段については別途検討。。

RESTful login

  • ログインする = 有効なログイン済み"カレント"ユーザーを作る
  • ログアウトする = 有効なログイン済み"カレント"ユーザーを削除する
# config/routes.rb
# --
  map.resources :users, :controller => "wj_users",
  :collection => {
    :current => :any
  } do |users|
  end
# app/controller/wj_users_controller.rb
# --
  def current
    case request.method
    when get
      # do nothing
      raise WebJourney::AuthenticationRequiredError.new unless login?
    when :put, :post
      do_login(params[:id], params[:password])
    when :delete
      do_logout
      return redirect_to(page_path(WjPage.top))
    end
    # respond cases except delete
    respond_to do |format|
      format.html { redirect_to page_path(current_user.find_or_create_start_page)}
      format.xml  { redirect_to user_path(current_user)}
    end
  end


こういうこと?
2008/01/07 追記 : ログインしていないときはGETは401を返すように。