FuelPHPをやってみる (21) - 認証機能 (1) -
SimpleAuthパッケージを使えば簡単に認証機能を組み込む事が出来る模様ですが、まだ未検証なので自前で認証機能を実装してみる
認証方式
単純にセッションにユーザーが認証済みかを検証できるようにする。でそのセッションにユーザーIDやパスワードを含ませるのはイケてない(それなりに暗号化すれば問題無いのかは微妙)。なのでログイン時にログインハッシュを発行して、それを元にログインをチェックする
で認証されているかをチェックするのを毎回コードで実装するのもあれなので、それを行うコントローラークラスを作りbeforeメソッドで処理を行う。
データベーステーブル構造
CREATE TABLE user(
id int auto_increment primary key,
userid varchar(30) not null unique,
password varchar(50) not null
salt varchar(255) not null
);
saltは64で十分なのだけど
ログインアクションを作る (fuel/app/classes/controller/auth.php)
<?php
class Controller_Auth extends Controller {
public function get_index() {
return View::forge("login");
}
public function post_login() {
// 入力情報から該当ユーザーを算出
$user = Model_User::find(
array(
"where" => array(
"userid" => Input::post("userid"),
"password" => sha1(Input::post("password"))
),
"limit" => 1
)
);
if (!is_null($user)) {
// ユーザーがマッチした場合にはsaltを更新する
$user = reset($user);
$user->salt = Str::random("sha2", 64);
$user->save();
// セッションに認証チェックに必要な情報を突っ込む
Session::set(
"current_user", array(
"id" => $user->id,
"salt" => $user->salt
)
);
}
Response::redirect("/");
}
public function get_logout() {
// ログアウト時はセッションを消してリダイレクト
Session::delete("current_user");
Response::redirect("/");
}
}
な感じ。ログインフォームに関しては単純なフォーム(userid,passwordを含むインプットのみ)なので省略。但し、今回書いてないけど本来はCSRFチェックしないとダメかと
認証チェックを行うコントローラークラスを作る
<?php
abstract class Controller_Secure extends Controller {
public function before() {
// 現在ログインしているセッションのデータを取得
$current_user = Session::get("current_user", null);
if (!is_null($current_user)) {
if (isset($current_user["id"]) and isset($current_user["salt"])) {
// セッションに格納されているユーザー情報から特定する
$user = Model_User::find(
array(
"where" => array(
"id" => $current_user["id"],
"salt" => $current_user["salt"]
)
)
);
if (!is_null($user) and count($user) > 0) {
// 存在していれば処理続行
return;
}
}
}
// 認証していないのでログインアクションへリダイレクト
return Response::redirect("/auth");
}
}
というような感じ。で要認証アクションで
<?php
class Controller_Home extends Controller_Secure {
public function get_index() {
return Response::forge("hello");
}
}
というように要認証が必要な場合にbeforeでチェックされるコントローラーを継承する
っていうような感じで作れば独自の認証方式を採用する事も出来るような感じかと