I have used this blog post to create the API, but with a couple of tweaks and some additional explanations. So, thanks Hendrik!
Pre-requisites
I'll assume that you have Laravel set up to use laravel commands.
First, create your application
Run:
laravel new sanctum-example
To question 'Would you like to install a starter kit?', select 'No starter kit'.
To question 'Which testing framework do you prefer?', select 'Pest'.
To question 'Would you like to initialize a Git repository?', select 'yes'.
To question 'Which database will your application use?', select 'MySQL'.
To question 'Would you like to run the default database migrations?', select 'no'.
Run:
cd sanctum-example
Run:
php artisan install:api
At this stage, the API script reports: "INFO API scaffolding installed. Please add the [Laravel\Sanctum\HasApiTokens] trait to your User model".
So, let's do that first.
Open app/Models/User.php and change the line:
use HasFactory, Notifiable;
to:
use HasApiTokens, HasFactory, Notifiable;
This will also require you to add the namespace:
use Laravel\Sanctum\HasApiTokens;
Now that's done:
Delete the resources directory
Delete the file routes/web.php
Delete the line web: __DIR__.'/../routes/web.php', from bootstrap/app.php
At this stage I like to create the database so that migrations can be added.
Run:
php artisan serve
Now open your favourite MySQL editor and create the database, i.e.
CREATE DATABASE `sanctum-example`;
Now we can close the server using Ctrl-c.
We should now edit our database settings in the .env file to something similar to this:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=sanctum-example
DB_USERNAME=root
DB_PASSWORD=<yourpassword>
We're now in a good place to do our migrations:
php artisan migrate
At this stage Sanctum doesn't have a configuration published. For this we have to run:
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
Create an Authentication Controller
Our application is API only, so we don't need to create a separate directory to hold API code. So, run:
php artisan make:controller AuthController
We should now have a file called app/Http/Controllers/AuthController.php
To this controller, let's add a method to handle registration:
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255',
'email' => 'required|string|max:255|unique:users',
'password' => 'required|string'
]);
if ($validator->fails()) {
return response()->json($validator->errors());
}
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password)
]);
$token = $user->createToken('auth_token')->plainTextToken;
return response()->json([
'data' => $user,
'access_token' => $token,
'token_type' => 'Bearer'
]);
}
A method to handle login:
public function login(Request $request)
{
$validator = Validator::make($request->all(), [
'email' => 'required|string|max:255',
'password' => 'required|string'
]);
if ($validator->fails()) {
return response()->json($validator->errors());
}
$credentials = $request->only('email', 'password');
if (!Auth::attempt($credentials)) {
return response()->json([
'message' => 'User not found'
], 401);
}
$user = User::where('email', $request->email)->firstOrFail();
$token = $user->createToken('auth_token')->plainTextToken;
return response()->json([
'message' => 'Login success',
'access_token' => $token,
'token_type' => 'Bearer'
]);
}
Finally, a method to handle logout:
public function logout()
{
Auth::user()->tokens()->delete();
return response()->json([
'message' => 'Logout successfull'
]);
}
In order to support these methods, you need to have the following namespaces at the top of your class:
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
Create Routes
Next we need to edit the file routes/api.php
We'll begin by adding our new namespace to the top of the file:
use App\Http\Controllers\AuthController;
Now we can add the routes to support the work we did in the AuthController.
A route for /user should already exist. Don't remove/override that, we'll need it later. Add:
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->group(function () {
Route::post('/logout', [AuthController::class, 'logout']);
});
Testing our work
Let's start the server again:
php artisan serve
I use Postman for this, but essentially, below are the values you need to perform in each test.
Register
Method: POST
URL: http://127.0.0.1:8000/api/register
Header fields: Accept: application/json
Body fields: name,email,password
Make up your own name, email address and password
Login
Method: POST
URL: http://127.0.0.1:8000/api/login
Headers fields: Accept: application/json
Body fields: email, password
Get User
Method: GET
URL: http://127.0.0.1:8000/api/login
Headers: Accept : application/json
Authorization: <Bearer token>
Make use of the token returned when you used the login or register API.
Logout
Method: POST
URL: http://127.0.0.1:8000/api/logout
Headers: Accept: application/json
Authorization: <Bearer token>
Make use of the token returned when you used the login or register API.
No comments:
Post a Comment