Trong bài viết này, bạn sẽ học cách sử dụng Framework Laravel của PHP để viết 1 RESTful Web Service API. Ứng dụng này sẽ có các RESTful API cho việc
- Đăng ký tài khoản mới (register)
- Đăng nhập (authentication)
- Thay đổi mật khẩu (change password)
Cấu trúc cơ sở dữ liệu (MySQL)
Chúng ta sẽ tạo bảng users trong cơ sở dữ liệu với cấu trúc sau:
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
email_verified_at DATETIME,
remember_token VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
Trong câu lệnh trên, chúng ta đã tạo bảng users với các trường sau:
id: trường khóa chính dạng số nguyên tự tăngname: trường dạng chuỗi lưu tên người dùngemail: trường dạng chuỗi lưu địa chỉ email của người dùng, không trùng lặppassword: trường dạng chuỗi lưu mật khẩu của người dùngemail_verified_at: trường dạng ngày giờ lưu thời điểm xác nhận email của người dùngremember_token: trường dạng chuỗi lưu mã token dùng để lưu trữ đăng nhập người dùng
Chú ý bạn không cần chạy lệnh SQL này, ở bước sau chúng ta sẽ dùng migrate của Laravel để thực hiện việc khởi tạo các bảng cơ bản của hệ thống.
Sử dụng Laravel Passport
Chúng ta muốn có 1 vài api đòi hỏi user phải đã đăng nhập thành công từ API /user/login.
user/login do đó sẽ trả về 1 chuỗi token để các api trong nhóm cần có đăng nhập có thể sử dụng. Để thực hiện được việc này, chúng ta sẽ sử dung Laravel Passport. Bạn hãy chạy các lệnh sau:
composer require laravel/passport
php artisan migrate
php artisan passport:install
Update file App\Providers\AuthServiceProvider với đoạn code sau:
protected $policies = [
'App\Models\Model' => 'App\Policies\ModelPolicy',
];
Cập nhật config/auth.php và thêm config cho api:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
Xây dựng Model cho bảng user
Để tạo model User cho một RESTful web service API bằng Laravel, bạn có thể sử dụng các bước sau:
- Tạo model
Userbằng cách sử dụng lệnhphp artisan make:model User -m. - Trong model, khai báo các validation rules cho các trường dữ liệu cần thiết cho các chức năng đăng ký, xác nhận, đăng nhập và thay đổi mật khẩu.
- Sử dụng trait
Illuminate\Foundation\Auth\VerifiesEmailsđể hỗ trợ chức năng xác nhận email.
Ví dụ:
<?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;
use Laravel\Passport\HasApiTokens;
use Illuminate\Foundation\Auth\VerifiesEmails;
use Illuminate\Database\Eloquent\Model;
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',
];
public static $registerRules = [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
];
public static $updatePasswordRules = [
'current_password' => 'required',
'password' => 'required|string|min:6|confirmed',
];
}
Xây dựng Controller cho Web Service API
Bây giờ, chúng ta sẽ tạo UserController để có các action cho việc tạo tài khoản mới, xác nhận qua email tài khoản vừa tạo, đăng nhập và thay đổi mật khẩu.
Để tạo UserController và các action cho việc tạo tài khoản mới, xác nhận qua email tài khoản vừa tạo, đăng nhập và thay đổi mật khẩu, bạn có thể thực hiện các bước sau:
- Tạo
UserControllerbằng cách sử dụng lệnhphp artisan make:controller UserController. - Trong
UserController, tạo các action sau:
register: action này dùng để tạo tài khoản mới bằng email và mật khẩu.verify: action này dùng để xác nhận tài khoản mới qua email.login: action này dùng để đăng nhập vào hệ thống bằng email và mật khẩu.updatePassword: action này dùng để thay đổi mật khẩu của người dùng.
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
class UserController extends Controller {
public function register(Request $request) {
$validator = Validator::make($request->all(), User::$registerRules);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
$user = new User();
$user->name = $request->name;
$user->email = $request->email;
$user->password = bcrypt($request->password);
$user->save();
return response()->json(['message' => 'Successfully registered'], 201);
}
public function verify(Request $request)
{
$user = User::find($request->id);
$user->email_verified_at = now();
$user->save();
return response()->json(['message' => 'Successfully verified'], 200);
}
public function login(Request $request)
{
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'password' => 'required',
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
$credentials = $request->only(['email', 'password']);
if (Auth::attempt($credentials)) {
$user = Auth::user();
if (!$user->email_verified_at) {
return response()->json(['errors' => 'Email not verified'], 401);
}
$token = $user->createToken('Laravel Password Grant Client')->accessToken;
return response()->json(['token' => $token], 200);
} else {
return response()->json(['errors' => 'Email or password is incorrect'], 401);
}
}
}
Giải thích thêm về action login:
- user->createToken(‘Laravel Password Grant Client’)->accessToken;` và trả về kết quả thành công và token vừa tạo. Nếu đăng nhập không thành công, chúng ta trả về kết quả lỗi và mã lỗi 401.
- Nếu người dùng chưa xác nhận email, chúng ta cũng trả về kết quả lỗi và mã lỗi 401.
- Lưu ý: trong code trên, chúng ta đã sử dụng thư viện
Illuminate\Support\Facades\Authđể sử dụng các hàm xác thực của Laravel. Bạn cũng có thể sử dụng các hàm xác thực trong thư việnIlluminate\Auth\AuthManagerthay vì sử dụng các hàm xác thực trongAuthfacade.
Với 3 API trên, bạn không cần phải yêu cầu user đăng nhập thành công trước khi có thể sử dụng chúng. Tuy nhiên, với Web Service API cập nhật mật khẩu, chúng ta cần yêu cầu người sử dụng đã đăng nhập thành công. Chúng ta thực hiện việc kiểm tra này thông qua token (Bearer Token) đã được cung cấp ở json trả về khi đăng nhập thành công qua api login().
Sử dụng Bearer Token trong RESTful Web Service
Để tạo action updatePassword trong UserController, bạn có thể sử dụng code sau:
public function changePassword(Request $request)
{
// Validate the request
$validator = Validator::make($request->all(), [
'password' => 'required|string|min:6',
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
// Check if the request has a valid Bearer token
if ($request->bearerToken()) {
// Get the authenticated user
$user = $request->user();
// Update the user's password
$user->password = bcrypt($request->password);
$user->save();
return response()->json(['message' => 'Password changed successfully'], 200);
} else {
// Return error if the request doesn't have a valid Bearer token
return response()->json(['error' => 'Unauthorized'], 401);
}
}
Trong action này, chúng ta sử dụng câu lệnh Validator::make để kiểm tra tính hợp lệ của dữ liệu được gửi lên từ client. Nếu dữ liệu không hợp lệ, chúng ta trả về kết quả lỗi và mã lỗi 422.
Sau đó, chúng ta sử dụng hàm $request->bearerToken() để kiểm tra xem API call có chứa Bearer token hay không. Nếu có, chúng ta lấy thông tin người dùng hiện tại từ biến $request->user(). Sau đó, chúng ta cập nhật mật khẩu mới cho người dùng bằng câu lệnh $user->password = bcrypt($request->password) và lưu lại thông tin người dùng bằng câu lệnh $user->save(). Cuối cùng, chúng ta trả về kết quả thành công và mã lỗi 200.
Nếu API call không chứa Bearer token, chúng ta trả về lỗi 401 cho user.
Để yêu cầu api call phải có bearer token, bạn có thể thêm middleware auth:api vào route của action changePassword trong file routes/api.php như sau:
Route::put('/user/change-password', 'App\Http\Controllers\UserController@changePassword')->middleware('auth:api');
Khai báo các route cho app
Để khai báo route cho các action trên, bạn có thể sử dụng code sau trong tệp routes/api.php của Laravel:
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
/* |-------------------------------------------------------------------------- | 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::post('user/register', 'App\Http\Controllers\UserController@register');
Route::post('user/verify', 'App\Http\Controllers\UserController@verify');
Route::post('user/authenticate', 'App\Http\Controllers\UserController@authenticate');
Route::post('user/password', 'App\Http\Controllers\UserController@updatePassword');
Route::post('user/login', 'App\Http\Controllers\UserController@login');
Route::get('login', 'App\Http\Controllers\UserController@login');
Route::get('/user/{id}', 'App\Http\Controllers\UserController@getUser')->middleware('auth:api');
Route::put('/user/change-password', 'App\Http\Controllers\UserController@changePassword')->middleware('auth:api');
Trong đoạn code trên, chúng ta đã khai báo các route cho các action register, verify, authenticate và updatePassword.
Đối với action changePassword, chúng ta đã khai báo nó trong 1 Route::group với middleware là auth:api, để yêu cầu API call phải có Bearer token hợp lệ mới có thể gọi đến action này.
Chạy kiểm thử RESTful Web Service API
Đăng ký người dùng mới:
curl -X POST \
http://localhost:8000/api/user/register \
-H 'Content-Type: application/json' \
-d '{
"name": "test",
"email": "user@example.com",
"password": "password123",
"password_confirmation: "password123"
}'
- Bạn chú ý phải có thêm input “password_confirmation” (tức là gõ lại password)
Xác nhận người dùng qua email:
curl -X POST \
http://localhost:8000/api/user/verify \
-H 'Content-Type: application/json' \
-d '{
"email": "user@example.com",
"verification_code": "123456"
}'
Đăng nhập người dùng:
curl -X POST \
http://localhost:8000/api/user/authenticate \
-H 'Content-Type: application/json' \
-d '{
"email": "user@example.com",
"password": "password"
}'
Thay đổi mật khẩu người dùng (yêu cầu Bearer token hợp lệ):
curl -X POST \
http://localhost:8000/api/user/password \
-H 'Authorization: Bearer ' \
-H 'Content-Type: application/json' \
-d '{
"password": "newpassword"
}'
Bạn cũng có thể tìm hiểu cách sử dụng Postman cho việc chạy thử RESTful Web Service API của Laravel. Tham khảo cách cài đặt Postman tại đây.

Pingback: ReactJS sử dụng Route và form để đăng ký account và đăng nhập - Bệ Phóng Việt
Pingback: ReactJS Bài 6: Dùng table với dữ liệu động - Bệ Phóng Việt