UnsplashのRobert Lukemanが撮影した写真
目次
今回は認証機能(サインイン、サインアウト)を実装します。
できるだけシンプルにコードを書くため、デザインは最小限にしてあります。
OS:Windows11 Home / WSL(Ubuntu20.04)
php:v7.4.33
phalcon:4.0.6
Phalcon DevTools:v4.2.0
DB:mysql v8.0.34
さっそく認証機能を実装していきます。
/app/config/router.phpに以下の赤字2行を追記します。
<?php
$router = $di->getRouter();
$router->add("/users/index", "Users::index");
$router->add("/users/show", "Users::show");
$router->add("/users/add", "Users::add");
$router->add("/users/edit", "Users::edit");
$router->add("/users/delete", "Users::delete");
$router->add("/users/signin", "Users::signin"); //追記
$router->add("/users/signout", "Users::signout"); //追記
$router->handle($_SERVER['REQUEST_URI']);
まず、サインイン用のビューを作成します。
「/app/view/users/signin.phtml」となるよう「signin.phtml」を作成し、以下記述してください。
<h2>users/signin</h2>
<?php
//ログイン失敗時のエラーメッセージ表示
if(!empty($errorMessage)){
echo "<p style='color:red;'>{$errorMessage}</p>";
}
?>
<button style="background:#aaa;width:100%;" onclick="location.href='/users/add'">ユーザーの新規登録</button>
<form action="#" method="post">
<p><label for="name">名前</label></p>
<p><input type="text" id="name" name="name" value=""></p>
<p><label for="password">パスワード</label></p>
<p><input type="password" id="password" name="password" value=""></p>
<button type="submit" name="operation" value="send">サインイン</button>
</form>
UsersController.phpに「signinAction」と「signoutAction」を追加します。
UsersController.phpに以下の赤字部分を追記してください。
<?php
declare(strict_types=1);
class UsersController extends ControllerBase
{
~~省略~~
public function signinAction(){
if($_POST['operation'] == "send"){
$user = Users::findFirst([
'name = :name:',
'bind' => ['name' => $_POST['name']],
]);
//ユーザー名がDBに無い場合の処理
if(empty($user)){
$errorMessage = "名前またはパスワードが間違っています";
$this->view->errorMessage = $errorMessage;
//コントローラを通らず「users/signin.phtml」を表示させる
return $this->view->pick('/users/signin');
}
//パスワードが合っているか判定
if(password_verify($_POST['password'], $user->password)){
//ログイン成功時の処理
$signinId = password_hash($user->name, PASSWORD_DEFAULT);
//クッキーにログインのための情報を格納
setcookie('signinId', $signinId, time()+60*60, '/', '', false, true);
//セッションにログインユーザーの情報を格納
$_SESSION['signinId'] = $signinId;
$_SESSION['name'] = $user->name;
$_SESSION['user_id'] = $user->id;
return $this->response->redirect("users/index");
}else{
//ログイン失敗時の処理
$errorMessage = "名前またはパスワードが間違っています";
$this->view->errorMessage = $errorMessage;
return $this->view->pick('/users/signin');
}
}
}
public function signoutAction(){
//クッキーの削除
setcookie('signinId', '', time()-1, '/', '', false, true);
//セッションの削除
session_destroy();
return $this->response->redirect('users/signin');
}
}
/app/controllers/ControllerBase.phpはUsersController.phpの親クラスです。
ControllerBase.phpを活用すると、各コントローラの全てのアクションの実行前に実行させる処理を設定できます。
/app/controllers/ControllerBase.phpを以下のように書き替えてください。
<?php
declare(strict_types=1);
use Phalcon\Mvc\Controller;
class ControllerBase extends Controller
{
public function initialize(){
//セッション開始
session_start();
//サインイン有無の確認:サインインしてなければサインインページに遷移させる
if($_SERVER['REQUEST_URI'] != '/users/signin' && $_SERVER['REQUEST_URI'] != '/users/add'){
if(empty($_SESSION['name'])){
return $this->response->redirect('users/signin');
}
}
//サインイン済みならサインインページにアクセスさせない
if($_SERVER['REQUEST_URI'] == '/users/signin'){
if(!empty($_SESSION['name'])){
return $this->response->redirect('users/index');
}
}
}
}
④までで認証機能は実装できたので、ヘッダーにサインインしたユーザー名を表示させてみます。
ビューのおおもとのファイルである「/app/views/index.phtml」にヘッダーをつくります。
/app/views/index.phtmlに以下の赤字部分を追記してください。
<!DOCTYPE html>
<html>
<head>
~~省略~~
</head>
<body>
<?php if(!empty($_SESSION['name'])): ?>
<header style="text-align:end;">
<p>ログインユーザー:<?= $_SESSION['name']; ?></p>
<p><a href='/users/signout'>ログアウト</a><p>
</header>
<?php endif; ?>
<div class="container">
<?php echo $this->getContent(); ?>
</div>
~~省略~~
</body>
</html>
これで認証機能の実装は完了です!!
以下のように表示されていればOKです!
【サインイン画面】URL:localhost:8000/users/signin
【サインイン後に遷移する画面】
今回はできるだけシンプルに認証機能を実装するため、デザインや仕様は必要最低限に留めています。
必要に応じてコードを書き換えてお使いください。