前提
フロントをnuxt.js、API側をlaravel8、DBにmysqlを使って認証機能付きSPAの環境構築をしていきます。
私の環境は下記の通りです。
OS: windows10
node.js: 14.17.6
php: 8.0.13
laravel: 8.83.8
nuxt: ^2.15.7
mysql: 8.0.13
下準備
作業ディレクトリの作成
$ mkdir sample-app
$ cd sample-app
以降は任意の場所に作成した新たなsample-appディレクトリ内で作業をしていきます。
laravel8の構築
先ずはlaravel8のインストールから
$ composer create-project "laravel/laravel=8.*" sample-api
$ cd sample-api
$ php artisan serve
ブラウザでlocalhost:8000と入力して下記画面が返ってこればOK
次にlaravelをインストールしてから最初に行う初期設定を済ましておく
'timezone' => 'Asia/Tokyo', // UTCから変更
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'ja', // enから変更
APP_NAME=Laravel
APP_ENV=local
APP_KEY=hogehoge
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=APIで使用するDB名を記入する
DB_USERNAME=APIで使用するmysqlのユーザー名を記入する
DB_PASSWORD=APIで使用するmysqlのパスワードを記入する
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DRIVER=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
これで初期設定が完了しました。
続いて認証機能の作成をしていきます。
laravelで認証機能を作成する方法はいくつか存在しますが、今回はsanctumを使っていきます。
$ composer require laravel/sanctum
$ php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
$ php artisan migrate
これで認証機能に必要な機能の追加と必要なテーブルの生成が完了しました。
次にシーダーを利用してデモアカウントを作成しましょう。
$ php artisan make:seeder UserTableSeeder
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB; //追加する
class UserTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
// デモアカウントを作成
DB::table('users')->insert([
'name' => 'test',
'email' => 'test@test',
'password' => bcrypt('test'),
]);
}
}
$ php artisan db:seed --class=UserTableSeeder
これでログイン用のデモアカウントができました。
次はログイン機能の作成です。
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\RegisterController; // 追加する
use App\Http\Controllers\Auth\LoginController; // 追加する
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::post('/register', [RegisterController::class, 'register']);// ユーザー登録
Route::post('/login', [LoginController::class, 'login']);// ログイン
Route::post('/logout', [LoginController::class, 'logout']);// ログアウト
続いてcontrollerを作成していきます。
$ php artisan make:controller Auth/RegisterController
$ php artisan make:controller Auth/LoginController
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Providers\RouteServiceProvider; // 追加する
use App\Models\User; // 追加する
use Illuminate\Http\RedirectResponse; // 追加する
use Illuminate\Support\Facades\Hash; // 追加する
use Illuminate\Support\Facades\Validator; // 追加する
use \Symfony\Component\HttpFoundation\Response; // 追加する
class RegisterController extends Controller
{
public function register(Request $request)
{
//入力バリデーション
$validator = Validator::make($request->all(),[
'name' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required'
]);
//バリデーションで問題があった際にはエラーを返す
if ($validator->fails()) {
return response()->json($validator->messages(), Response::HTTP_UNPROCESSABLE_ENTITY);
}
//バリエーションで問題がなかった場合にはユーザを作成する
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
//ユーザの作成が完了するとjsonを返す
$json = [
'data' => $user,
'message' => 'User registration success!',
'error' => ''
];
return response()->json( $json, Response::HTTP_OK);
}
}
登録処理はこれで完了です。
POSTMAN等を利用してアカウント登録のテストをして成功するか確認してみましょう。
下記のようなjsonが返ってきたら成功です。
{
"data": {
"name": "hoge",
"email": "hoge@hoge",
"updated_at": "2022-04-19T02:12:36.000000Z",
"created_at": "2022-04-19T02:12:36.000000Z",
"id": 2
},
"message": "User registration success!",
"error": ""
}
※もしくは自身のDBを確認して新たなアカウントが追加されているかを確認してみましょう。
アカウント登録の処理が完成したら次はログイン処理を作成していきましょう。
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; // 追加する
use Illuminate\Validation\ValidationException; // 追加する
use App\Models\User; // 追加する
use \Symfony\Component\HttpFoundation\Response; // 追加する
class LoginController extends Controller
{
public function login(Request $request){
// バリデーション
$credentials = $request->validate([
'email' => 'required|email',
'password' => 'required'
]);
// ログイン処理
if(Auth::attempt($credentials)){
$user = User::whereEmail($request->email)->first(); //トークン作成と取得
$user->tokens()->delete();
$token = $user->createToken("login:user{$user->id}")->plainTextToken;
//ログインが成功するとtokenを返す。
return response()->json(['token' => $token], Response::HTTP_OK);
}
// ログイン失敗時の処理
return response()->json('Can Not Login.', Response::HTTP_INTERNAL_SERVER_ERROR);
}
public function logout(Request $request){
auth('sanctum')->user()->tokens()->delete();
return response(['message' => 'You have been successfully logged out.'], 200);
}
public function user(Request $request){
$user = $request->user();
return response()->json(compact('user'), 200);
}
}
これでログインの処理は完成です。
ちゃんとログインできるか、POSTMAN等を利用してAPIの動作確認をしていきましょう。
emailとpasswordをbodyに書いて渡します。
今回は先程作成したメールアドレスtest@test
とパスワードtest
を利用してログインしていきます。
尚、ログインのURLはhttp://localhost:8000/api/login
です。
下記のようなjsonが返ってきたら成功です。
{
"token": "1|VVmQ0GlY9pjwQyIev9ou7Octpx9ZMQa9xhhFuhOe"
}
これで完成です。
最後にtokenが発行されていないと処理できないrouteを作成しておきます。
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\RegisterController; // 追加する
use App\Http\Controllers\Auth\LoginController; // 追加する
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::post('/register', [RegisterController::class, 'register']); // ユーザー登録
Route::post('/login', [LoginController::class, 'login']); // ログイン
Route::post('/logout', [LoginController::class, 'logout']); // ログアウト
//ログインしたユーザーのみが/hogeにアクセスできる
Route::middleware('auth:sanctum')->group(function(){
Route::get('/hoge', function(){
return 'auth is working';
});
});
最後にAPIとして利用する為に細かな設定をいくつかしないといけません。
あとちょっと。
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true, // 変更する
];
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, // コメントアウトを外す
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
↑大体43行目あたり
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array<int, string>
*/
protected $except = [
'api/register', // 追記する
'api/login' // 追記する
];
}
以上になります。
本APIで発行したtokenを受け取るnuxt.js側の環境構築は別記事に書いていきます。
お疲れ様でした!
次のステップ