スポンサーリンク

2015年7月14日

[Elixir+Phoenix]Add the session to the login

Goal

Phoenix Guide Sessionsを実施する。
ログイン処理でセッションを利用する。

Dev-Environment

OS: Windows8.1
Erlang: Eshell V6.4, OTP-Version 17.5
Elixir: v1.0.4
Phoenix Framework: v0.13.1
PostgreSQL: postgres (PostgreSQL) 9.4.4

Wait a minute

先に記述しておきます。
Erlang/OTPを利用した方法は実施しません。
ここでは、Phoenixでのセッションの使い方を学びます。
また、ログインの処理でセッションを利用します。

Index

  1. How do session?
  2. Let’s try!!
  3. Use the login
  4. Create my Plug(Authentication)
  5. Extra

1. How do session?

嬉しいことに、Phoenix - Guide Sessionsを記事にしている方がいる。
本家と見比べながら実施していく。
Qiita - Phoenix Framework docs/sessions読んだ。
セッションとクッキーの違いについては以下の記事が分かりやすかった。
Qiita - クッキーとセッションの違い
Phoenixは、デフォルトでPlugのCookieセッションストレージを使用できる。
設定をしているファイルが以下の二つ。
ファイル: config/config.exs
secret_key_base:、session:の設定を行う。
config :sample_app, SampleApp.Endpoint,
  url: [host: "localhost"],
  root: Path.dirname(__DIR__),
  secret_key_base: "****",
  debug_errors: false,
  pubsub: [name: SampleApp.PubSub,
           adapter: Phoenix.PubSub.PG2],
  session: [store: :cookie,
            key: "_your_app_key"]
Description:
secret_key_base:は、プロジェクトが生成された時に
値も生成されているので特に設定することはない。
secret_key_base値は、各クッキーに署名するために使用されている。
Plug.Sessionの設定が書いているファイル。
ファイル: lib/プロジェクト名/endpoint.ex

2. Let’s try!!

セッションを利用する一番簡単な例は以下になる。
Example:
defmodule SampleApp.PageController do
  use Phoenix.Controller

  def index(conn, _params) do
    conn = put_session(conn, :message, "hoge")
    message = get_session(conn, :message)

    text conn, message
  end
end
Description:
put_session/2を使い値を格納する。
Description:
get_session/2を使い値を取り出す。

3. Use the login

ログインの処理で使っていきます。
ファイル: web/controllers/session_controller.ex
put_session/2でuserのidを格納する。
def create(conn, %{"login_params" => %{"email" => email, "password" => password}}) do
  case login(email, password) do
    {:ok, user} ->
      conn
      |> put_flash(:info, "User login is success!!")
      |> put_session(:user_id, user.id)
      |> redirect(to: static_pages_path(conn, :home))
    :error ->
      conn
      |> put_flash(:error, "User login is failed!! email or password is incorrect.")
      |> redirect(to: session_path(conn, :new))
  end
end

4. Create my Plug(Authentication)

Plugから利用できる自分で定義したPlugを作成する。
こちらの方のプロジェクト(ソースコード)を参考にした。
Github - janjiss/elixir-stream-phoenix
ファイル: lib/plugs/check_authentication.ex
defmodule SampleApp.Plugs.CheckAuthentication do
  import Plug.Conn
  import Plug.Session

  def init(options) do
    options
  end

  def call(conn, _) do
    user_id = get_session(conn, :user_id)
    if session_present?(user_id) do
      assign(conn, :current_user, SampleApp.Repo.get(ElixirStream.User, user_id))
    else
      conn
    end
  end

  def session_present?(user_id) do
    case user_id do
      nil -> false
      _   -> true
    end
  end
end
ファイル: web/controllers/session_controller.ex
以下の一行を記述して下さい。
plug SampleApp.Plugs.CheckAuthentication
ファイル: web/views/layout_view.ex
現在のユーザを取得するためのメソッドを定義します。
def current_user(conn) do
  conn.assigns[:current_user]
end
ファイル: web/templates/layout/footer.html.eex
フッターに表示して動作を確認する。
<div class="jumbotron">
  <%= if current_user(@conn) do %>
    <p>Current UserName: <%= current_user(@conn).name %></p>
  <% end %>
</div>
これでログインしたユーザが表示される。
保持しているデータを削除しない限りは残るので、
タブを消すかブラウザを消しても再度表示される。
ログインの永続化を行うための準備もできた。

5. Extra

以下のコントローラへ・・・
ファイル: web/controllers/static_page_controller.ex
ファイル: web/controllers/user_controller.ex
ファイル: web/controllers/page_controller.ex
以下の定義を追加すれば・・・
plug SampleApp.Plugs.CheckAuthentication
SessionControllerを使って表示しているページ以外でも・・・
現在のユーザが表示されるようになる。
(実際は、必要なコントローラにだけ定義して利用すること)

Speaking to oneself

ElixirStreamに登録しました。
現在あのサイトが私にとって一番、PhoenixのTipsで役に立っています。
気になったら見てみると良いかと・・・
Plugをそろそろ本格的にやらんといかんね・・・
使うことはできるけど、動作が分からん。
何かあった時、対処できなくなる恐れがある。

Bibliography

人気の投稿