🐘
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) {
$error = $request["error"];
return view("sign_up.index", compact("error"));
}
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 ($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) {
$error = $request["error"];
return view("login.index", compact("error"));
}
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 ($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