Plugを使用してアクションの前にフィルターを実装する
##Plugとは
Railsでの before_action
のようなフィルター処理をPhoenixでどう実装するものかと調べた結果
Plugで実装できそうでした。
Plug lives at the heart of Phoenix's HTTP layer, and Phoenix puts Plug front and center. We interact with plugs at every step of the connection lifecycle, and the core Phoenix components like Endpoints, Routers, and Controllers are all just Plugs internally. Let's jump in and find out just what makes Plug so special.
We interact with plugs at every step of the connection lifecycle
簡単にPlugを説明すると コネクションの 各ステップで処理を挟める という認識です。
例として, ユーザがログインしてるか(cookieに:idがsetされているか)どうかの判断をPlugで実装していきます。
##Plugでのフィルター実装
今回はControllerのアクションの前にフィルターとなる処理を挟みます。
- フィルターとなるPlugを作成する。
- web.ex でcontrollerに フィルターとなるPlugのメソッドをimportする
- Controller でPlugを呼び出す
フィルターとなるPlugを作成する
#web/controllers/authenticator.ex
defmodule Example.Authenticator do
import Plug.Conn
import Phoenix.Controller
def logged_in?(conn, _opts) do
case get_session(conn, :id) do
nil ->
conn
|> redirect(to: "/signin")
|> halt
_ -> conn
end
end
end
コードから推測できると思いますが, cookieに id
がなければ, /signin
にリダイレクトするというシンプルな処理です。
web.ex でcontrollerに フィルターとなるPlugのメソッドをimportする
def controller do
quote do
use Phoenix.Controller
alias Example.Repo
import Ecto
import Ecto.Query
import Example.Router.Helpers
import Example.Gettext
import Example.Authenticator, only: [logged_in?: 2]
end
end
import Example.Authenticator, only: [logged_in?: 2]
上で定義したPlugをimportする。
今回は特にonlyの記述は必要ないが, 特定のmethodをimportしたい場合は onlyでメソッド名, paramの数を指定する。
これで定義されているController全てでAuhenticatorのlogged_in?
が呼べるようになりました。
Controller でPlugを呼び出す
defmodule Example.xxxxxxController do
use Example.Web, :controller
alias Example.UserProfile
plug :logged_in?
plug :logged_in?
を アクションの前に呼び出したいControllerに追加します。
以上で before_action
のような処理を追加できました。