初めての記事ですが、軽くSanctumを使用してAPI作成を紹介していきたいと思います。よろしくお願いします。
●ログイン者のみアクセスできるAPIを作成
●環境:Laravel8
新しいプロジェクトを作成します。
create project laravel/laravel sanctum_test
.envファイルの設定を自分の環境と合わせて修正します。
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db_name
DB_USERNAME=root
DB_PASSWORD=
Sanctumパッケージをインストール
composer require laravel/sanctum
app/Http/Kernel.phpにapiミドルウェア設定を行います。追加されている場合、コメントアウトを外します。
修正前:
protected $middlewareGroups = [
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
],
];
修正後:
protected $middlewareGroups = [
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
],
];
マイグレートを実行しデフォルトのユーザモデルにSanctumの設定を追加
php artisan migrate
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
//Sanctum
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
app\Http\Controllersにログイン処理を作成
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use \Symfony\Component\HttpFoundation\Response;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller{
public function index(Request $request)
{
$email = $request->email;
$password = $request->password;
//バリデーション
$credentials = $this->validator($request);
if(Auth::attempt($credentials)){
$user = User::where('email', $email)->first();
if($user && Hash::check($password, $user->password)){
//既存トークン削除
$user->tokens()->delete();
$user->email_verified_at = new Carbon ('now');
$user->save();
$result = [
'token' => $user->createToken("login:user{$user->id}")->plainTextToken
];
return response()->json($result, Response::HTTP_OK);
}
}
}
/**
* @param Request $request
* @return array
*/
protected function validator(Request $request)
{
return $this->validate($request, [
'email' => 'required',
'password' => 'required'
]);
}
}
routes/api.phpにルートを設定
Route::post('/login', 'App\Http\Controllers\LoginController@index')->name('login');
作成したログインAPIをPostmanでアクセスしてみると!
次は上記のトークンでログイン者のみアクセルできるAPIを作成いたします。まず新しいModelを作成
php artisan make:model Article
Articleテーブル用のダミーデータを作成してArticleFactory.phpに以下を追加
php artisan make:factory ArticleFactory
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class ArticleFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'title' => $this->faker->sentence,
'body' => $this->faker->paragraph,
'category_id' => rand (1,5)
];
}
}
DatabaseSeeder.phpにも追加
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Article;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
Article::factory()->count(20)->create();
}
}
ダミーデータSeedを実行します。これでデータの準備が終わりました。作成したArticleテーブルのデータを取得するAPIの作成を進みます。
php artisan db:seed
Article取得APIを作成.「--api」オプションをつけたのでCRUDの関数が揃っている状態ですが、
今回はindex関数のみに使います。
php artisan make:Controller ArticleApiController --api
ArticleApiControllerに以下の処理を追加
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use Illuminate\Http\Request;
class ArticleApiController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return Article::all();
}
}
またルートを設定
//Sanctum認証
Route::middleware('auth:sanctum')->group(function(){
Route::get('/articles','App\Http\Controllers\ArticleApiController@index');
});
Postmanの認証設定で発行されたトークンを入れてアクセスするとちゃんと返しています。
今回違うトークンを使ってみると認証失敗となっています。これで終わりですが、よかったら参考してください。最後まで読んでくれてありがとう!