🐘
Laravel入門6 Todoアプリ(認証機能)
記事一覧
- Laravel × Docker 最速環境構築
 - Laravel 入門1 ページ追加
 - Laravel入門2 bladeディレクティブ
 - Laravel入門3 静的ファイル
 - Laravel入門4 Request
 - Laravel入門5 Todoアプリ(データベース)
 - Laravel入門6 Todoアプリ(認証機能)
 - Laravel入門7 Todoアプリ(CRUD)
 
認証機能
認証機能とは
ログインやサインアップ周りの機能
View
- 以下のファイルを作成
 
- login/index.blade.php
 - sign_up/index.blade.php
 - task/index.blade.php
 
.
├── laravel_app
│   └── resources
│       └── views
│           ├── login
│           │   └── index.blade.php # ログインページ
│           ├── sign_up
│           │   └── index.blade.php # サインアップページ
│           └── task
│               └── index.blade.php # タスク一覧ページ(ログイン後)
├── mysql_data
├── docker-compose.yml
└── Dockerfile
- ファイルを記述
 
- login/index.blade.php
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <h1>ログインページ</h1>
    {{-- 【重要】login.storeのルーティングは後で作成する --}}
    <form action="{{ route("login.store") }}" method="POST">
        {{-- フォームのメソッドがPOSTの場合は、csrfトークンを設定する必要がある --}}
        {{-- (@csrfと書くだけでOK) --}}
        @csrf
        <label for="email">メールアドレス</label>
        <input type="email" name="email">
        <label for="password">パスワード</label>
        <input type="password" name="password">
        <button type="submit">ログイン</button>
    </form>
</body>
</html>
- sign_up/index.blade.php
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <h1>サインアップページ</h1>
    {{-- 【重要】sign_up.storeのルーティングは後で作成する --}}
    <form action="{{ route('sign_up.store') }}" method="POST">
        {{-- フォームのメソッドがPOSTの場合は、csrfトークンを設定する必要がある --}}
        {{-- (@csrfと書くだけでOK) --}}
        @csrf
        <label>名前</label>
        <input type="text" name="name">
        <label>メールアドレス</label>
        <input type="email" name="email">
        <label>パスワード</label>
        <input type="password" name="password">
        <label>パスワード確認</label>
        <input type="password" name="passwordConfirmation">
        <button type="submit">サインアップ</button>
    </form>
</body>
</html>
- task/index.blade.php
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <h1>タスク一覧ページ</h1>
    {{-- 後の記事で記述 --}}
</body>
</html>
Controller
- 以下のファイルを作成
 
- LoginController.php
 - SignUpController.php
 - TaskController.php
 
コンテナ内に入る
docker compose run app bash
コントローラー作成コマンドを実行
php artisan make:controller LoginController
php artisan make:controller SignUpController
php artisan make:controller TaskController
以下ファイルが生成されればOK
.
├── laravel_app
│   └── app
│       └── Http
│           └── Controllers
│               ├── LoginController.php # ログイン用
│               ├── SignUpController.php # サインアップ用
│               └── TaskController.php # タスク用
├── mysql_data
├── docker-compose.yml
└── Dockerfile
- ファイルを記述
 
- LoginController.php
 
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class LoginController extends Controller
{
    function index() {
        return view("login.index");
    }
}
- SignUpController.php
 
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SignUpController extends Controller
{
    function index() {
        return view("sign_up.index");
    }
}
- TaskController.php
 
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TaskController extends Controller
{
    function index() {
        return view("task.index");
    }
}
web.php
- web.phpを編集
 
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TopController;
use App\Http\Controllers\LoginController; # ログインコントローラー
use App\Http\Controllers\SignUpController; # サインアップコントローラー
use App\Http\Controllers\TaskController; # タスクコントローラー
Route::get('/', function () {
    return view('welcome');
});
Route::get('/top', [TopController::class, 'index'])->name("top");
// Route::prefix("共通のパス")->group(function() {
// prefixを使うと、共通のパスを持つルーティングをまとめることができる
Route::prefix('sign_up')->group(function () {
    // サインアップフォーム
    Route::get('/', [SignUpController::class, 'index'])->name("sign_up");
    // サインアップ処理
    Route::post('/', [SignUpController::class, 'store'])->name("sign_up.store");
});
Route::prefix('login')->group(function () {
    // ログインフォーム
    Route::get('/', [LoginController::class, 'index'])->name("login");
    // ログイン処理
    Route::post('/', [LoginController::class, 'store'])->name("login.store");
});
Route::prefix('task')->group(function () {
    // タスク一覧ページ
    Route::get('/', [TaskController::class, 'index'])->name("task");
});
サインアップ
- 
SignUpController.phpを編集 
- SignUpController.php
 
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User; // Userモデルを使用する
use Illuminate\Support\Facades\Hash; // パスワードのハッシュ化
class SignUpController extends Controller
{
    // エラーを受け取るためにRequestを追加
    function index(Request $request) {
        return view("sign_up.index");
    }
    function store(Request $request) {
        // それぞれの入力値を取得
        $name = $request["name"];
        $email = $request["email"];
        $password = $request["password"];
        $passwordConfirmation = $request["passwordConfirmation"];
        // パスワードが一致するかどうか
        if ($password !== $passwordConfirmation) {
            $error = "パスワードが一致しません";
            return view("sign_up.index", compact("error"));
        }
        // where('カラム名', 値) 絞り込み
        // exists() データが存在するかどうかtrue or falseを返す
        // メールアドレスが既に登録されているかどうか
        if (User::where('email', $email)->exists()) {
            $error = "既に登録されているメールアドレスです";
            return view("sign_up.index", compact("error"));
        }
        // create(連想配列) データを追加する
        $user = User::create([
            'name' => $name,
            'email' => $email,
            'password' => Hash::make($password), // パスワードをハッシュ化して保存
        ]);
        // auth()->login($user) ログイン処理
        auth()->login($user);
        return redirect()->route('task');
    }
}
- 
sign_up/index.blade.phpを編集 
- sign_up/index.blade.php
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <h1>サインアップページ</h1>
    <form action={{ route('sign_up.store') }} method="POST">
        @csrf
        <label>名前</label>
        <input type="text" name="name">
        <label>メールアドレス</label>
        <input type="email" name="email">
        <label>パスワード</label>
        <input type="password" name="password">
        <label>パスワード確認</label>
        <input type="password" name="passwordConfirmation">
        <button type="submit">サインアップ</button>
    </form>
    {{-- エラーがある場合に表示する --}}
    @if (!empty($error))
        <p>{{ $error }}</p>
    @endif
</body>
</html>
- http://localhost:8000/sign_upにアクセスしてサインアップ機能を確認
 
エラーのメッセージが表示されているかなども確認できるとGood

ログイン
- 
LoginController.phpを編集 
- LoginController.php
 
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User; // Userモデルを使用
use Illuminate\Support\Facades\Hash; // ハッシュパスワードのチェックに使用
class LoginController extends Controller
{
    // エラーを受け取るためにRequestを追加
    function index(Request $request) {
        return view("login.index");
    }
    function store(Request $request) {
        // それぞれの入力値を取得
        $email = $request["email"];
        $password = $request["password"];
        // emailで絞り込み
        $user = User::where('email', $email)->first();
        // ユーザーが存在しない場合 or パスワードが一致しない場合にエラーを返す
        // Hash::check()でパスワードのチェックを行える
        if (!$user || !Hash::check($password, $user->password)) {
            $error = "メールアドレスまたはパスワードが間違っています";
            return view('login.index', compact("error"));
        }
        // auth()->login($user) ログイン処理
        auth()->login($user);
        return redirect()->route("task");
    }
}
- 
login/index.blade.phpを編集 
- login/index.blade.php
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <h1>ログインページ</h1>
    <form action={{ route("login.store") }} method="POST">
        @csrf
        <label for="email">メールアドレス</label>
        <input type="email" name="email">
        <label for="password">パスワード</label>
        <input type="password" name="password">
        <button type="submit">ログイン</button>
    </form>
    {{-- エラーがある場合に表示する --}}
    @if (!empty($error))
        <p>{{ $error }}</p>
    @endif
</body>
</html>
認可ルーティング
認可ルーティングとは
ログイン後にのみアクセス可能なルーティング
-> 未ログインユーザーがアクセスしようとすると、ログインページなどにリダイレクトされる
- web.php
 
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TopController;
use App\Http\Controllers\LoginController;
use App\Http\Controllers\SignUpController;
use App\Http\Controllers\TaskController;
Route::get('/', function () {
    return view('welcome');
});
Route::get('/top', [TopController::class, 'index'])->name("top");
Route::prefix('sign_up')->group(function () {
    Route::get('/', [SignUpController::class, 'index'])->name("sign_up");
    Route::post('/', [SignUpController::class, 'store'])->name("sign_up.store");
});
Route::prefix('login')->group(function () {
    Route::get('/', [LoginController::class, 'index'])->name("login");
    Route::post('/', [LoginController::class, 'store'])->name("login.store");
});
// `Route::middleware('auth')->group(function () {` 内に入れると認可ルーティングになる
Route::middleware('auth')->group(function () {
    Route::prefix('task')->group(function () {
        Route::get('/', [TaskController::class, 'index'])->name("task");
    });
});



Discussion