Rails Tutorialやってみた! 17(8章-1)

公開日:2019-03-22
最終更新:2019-03-22

100DaysOfCode 19/100

8章 基本的なログイン機構

セッション

  • HTTPはステートレス(状態のない)なプロトコル

HTTPは言ってみれば、リクエストが終わると何もかも忘れて次回最初からやり直す健忘症的なプロトコルであり、過去を捨てた旅から旅の流れ者的なプロトコルです (しかし、だからこそこのプロトコルは非常に頑丈なのです)。

HTTPにできないことは、別レイヤーでやる必要があります。

ログイン状態を保存して、ページを遷移してもログインが継続するようなWebアプリケーションでは、セッションという半永続的な通信をクライアント―サーバー間に設定します。

セッションの実装としては、

  • sessionsメソッドを使った一時セッション
  • cookiesメソッドを使った、より長続きするセッション

があります。

セッションもRESTfulに

  • ログインページではnewで新しいセッションを出力
  • ログイン成功時、createで実際のセッションを作成
  • ログアウト時、destroyでセッションを破棄

このように考えれば、これまでのRESTfulアーキテクチャと同じようにセッションを理解できます。

これまでと違うのは、例えばUsersはデータベースに保存された永続的なデータにアクセスするのに対し、
セッションはcookiesという一時的なデータを参照元とする点です。

コントローラーの作成

これまでと流れは同じですが、rails generate contollerで自動作成される内容には今回不要なものもあるので、適宜カスタマイズしていきます。

  • rails routesでこれまで作成した名前付きルーティングの一覧が見られる

ビューの作成

続いてview、つまりログインフォームです。

form_forの使い方

  • セッションにはモデルに相当するものがない
form_for(:session, url: login_path)  

このように、リソースの名前と対応するURLの指定が必要

リスト 8.4で定義したフォームで送信すると、Sessionsコントローラのcreateアクションに到達します。Railsはこれをどうやって実現しているでしょうか? 考えてみてください。

ログインフォームはPOSTリクエストを送信するので、/loginにおけるPOSTリクエスト = createアクションに移動します。

最低限のcreateアクションを用意

今回、createアクションに対応するビューは存在しないので、このままだとsubmitボタンを押した際にエラーとなってしまいます。

def create  
  render 'new'  
end  

これから認証機能を実装していくため、いったんcreateアクション内で再度newビューを描画することで、画面遷移時にエラーとなることを防ぎます。

認証機能

ログインフォームに入力された情報をデータベースと照合し、認証を行う機能を作成していきます。

再度おさらいですが、フォームの情報を受け取るにはparams を用います。
params は入れ子ハッシュ構造になっています。

{ session: { password: "foobar", email: "[email protected]" } }  

つまりparams[:session][:email]のように記述して、ログインフォームに入力された内容を受け取ればOKです。

認証はメールアドレスからユーザーを探し、見つけたユーザーのパスワードと一致するかどうかをチェックすればよさそうです。

過去の章で学んだUser.find_byauthenticateがあれば実現できますね!

authenticate は認証成功時にユーザーオブジェクトを返し、失敗時にfalseを返します。

def create  
    user = User.find_by(email: params[:session][:email].downcase)  
    if user && user.authenticate(params[:session][:password])  
      # ユーザーログイン後にユーザー情報のページにリダイレクトする  
    else  
      # エラーメッセージを作成する  
      render 'new'  
    end  

そこで、ここでのif文は変数user(User.find_byで見つけてきたユーザーのユーザーオブジェクト)
修正: 勘違いしていました。User.find_byの戻り値自体をそのまま比較に使っているわけではなく、
Rubyはnilとfalse以外の戻り値は真偽値としてはすべてtrueになるという仕様を利用しています。

authenticateの戻り値が等しいかを確かめています。

  • User.find_byでユーザーを見つけられなかった(存在しなかった)場合、変数usernilになる
  • authenticateに失敗した場合、falseになる

つまり、右辺と左辺が一致するのは認証成功時のみです。
一瞬面食らいましたが、順を追って理解すれば納得ですね。

終わりに

過去に学んだ内容が必要になることが増えてきましたね。
書いてあることがよくわからない場合は、そのまま進まずにまず見直すよう心がけます。

記事が少しでもいいなと思ったらクラップを送ってみよう!
0
+1
@tammcの技術ブログ

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする