一般に、Authenticationを行うためにはSessionは不要ですが、ログイン管理を行う場合は便利なものです。ログイン管理という言葉が適切かどうかはわかりませんが、ログインのuser_idをブラウザ側とサーバ側で共有するための管理を意味しています。一般的にhttpはsession lessなので、Webアプリで改めて枠組みを提供する必要があります。
Phoenixではプロジェクト作成を作成したら、嬉しいことにSessionの初期設定が行われています。今回はそれを見ていきたいと思います。
1.Plug.Session
PhoenixでSessionを使う場合は、Plug.Sessionを利用します。公式ドキュメントは以下にあります。
https://hexdocs.pm/plug/Plug.Session.html#content
プロジェクトを作成すると、以下のようなendpoint.exファイルが生成され、Plug.Sessionの設定があります。ここではcoockieを使うことが明示されています。(ちなみにxxxxxはプロジェクト名です。)
# The session will be stored in the cookie and signed,
# this means its contents can be read but not tampered with.
# Set :encryption_salt if you would also like to encrypt it.
plug Plug.Session,
store: :cookie,
key: "_xxxxx_key",
signing_salt: "mspqDd7s"
sessionはPlug.Connの関数を通してアクセスできますが、最初にPlug.Conn.fetch_session で cookie と sessionを取得しておく必要があります。必要な関数は「2.Plug.Connが提供する関数」で説明します。ここではrouterのpipelineでPlug.Conn.fetch_sessionが利用されていることを確認しておきます。つまりbrowserを通したアクセスには必ずこの関数が呼ばれます。
---
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session ### <=====これです
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
---
2.Plug.Connが提供する関数
実際にsessionを利用するためには、Plug.Connの関数が必要になります。公式ドキュメントから関連のある関数をピックアップしてみました。
https://hexdocs.pm/plug/Plug.Conn.html#content
・session store(cookie)からsessionを取り出します。connとoptsの引数があるので、plug関数です。
fetch_session(conn, opts \\ [])
・sessionの中のkeyに対するvalueを返します。
get_session(conn, key)
・keyに対するvalueをsessionの中に書き込みます。
put_session(conn, key, value)
・sessionの設定変更を行います。
configure_session(conn, opts)
・sessionのkeyの項目を削除します。
delete_session(conn, key)
以上の関数の使われ方ですが、ログイン/ログアウトを想定して見ていきたいと思います。
まずユーザ登録やログイン認証に成功したら、sessionにuser_idをセットします。
put_session(conn, :user_id, user.id)
次にログインが成功したら session fixation attacks でセッションが乗っ取られるのを防ぐために、クライアントブラウザに対してsessionの更新を行います。
configure_session(conn, renew: true)
ログインしているかをチェックするためにsessionからuser_idを取り出します。user_idが取り出せればログインしていると判断し、user_idを使ってデータベースからuser情報を取り出します。
user_id = get_session(conn, :user_id)
ログアウト時はsessionを破棄しますが2つの選択肢があります。以下のどちらでも良いです。
1.session全体を破棄する場合。
configure_session(conn, drop: true)
2.sessionは残しておいて、user_idだけを破棄する場合。
delete_session(conn, :user_id)
以上です。
■ Elixir/Phoenixの基礎についてまとめた過去記事
Elixir Ecto チュートリアル - Qiita
Elixir Ecto のまとめ - Qiita
[Elixir Ecto Association - Qiita]
(https://qiita.com/sand/items/5581497972473e308f05)
Phoenix1.3の基本的な仕組み - Qiita
Phoenixのログイン管理のためのSessionの使い方 - Qiita
Phoenix1.3のUserアカウントとSession - Qiita
Phoenix1.3+Guardian1.0でJWT - Qiita