การตรวจสอบสิทธิ์ผู้ใช้และการควบคุมการเข้าถึงแบบเต็ม – บทช่วยสอน Laravel Passport, Pt. 1
เผยแพร่แล้ว: 2022-03-11เมื่อพัฒนาเว็บแอปพลิเคชัน โดยทั่วไปควรแบ่งออกเป็นสองระดับ API ระดับกลางโต้ตอบกับฐานข้อมูล และระดับเว็บมักจะประกอบด้วย Front-end SPA หรือ MPA วิธีนี้จะทำให้เว็บแอปพลิเคชันมีความเกี่ยวข้องกันมากขึ้น ทำให้ง่ายต่อการจัดการและแก้ไขจุดบกพร่องในระยะยาว
เมื่อสร้าง API แล้ว การตั้งค่าการรับรองความถูกต้องและสถานะในบริบท API แบบไร้สัญชาติอาจดูค่อนข้างมีปัญหา
ในบทความนี้ เราจะมาดูวิธีการใช้การพิสูจน์ตัวตนผู้ใช้แบบเต็มและรูปแบบการควบคุมการเข้าถึงอย่างง่ายใน API โดยใช้ Laravel และ Passport คุณควรมีประสบการณ์ในการทำงานกับ Laravel เนื่องจากนี่ไม่ใช่บทแนะนำเบื้องต้น
ข้อกำหนดเบื้องต้นในการติดตั้ง:
- PHP 7+, MySQL และ Apache (นักพัฒนาที่ต้องการติดตั้งทั้งสามพร้อมกันสามารถใช้ XAMPP)
- นักแต่งเพลง
- Laravel 7
- หนังสือเดินทาง Laravel เนื่องจากโดยทั่วไปแล้ว API จะไม่มีสถานะและไม่ใช้เซสชัน เราจึงมักใช้โทเค็นเพื่อรักษาสถานะระหว่างคำขอ Laravel ใช้ไลบรารี Passport เพื่อใช้งานเซิร์ฟเวอร์ OAuth2 เต็มรูปแบบที่เราสามารถใช้สำหรับการตรวจสอบสิทธิ์ใน API ของเรา
- บุรุษไปรษณีย์ cURL หรือ Insomnia เพื่อทดสอบ API—ขึ้นอยู่กับความชอบส่วนบุคคล
- โปรแกรมแก้ไขข้อความที่คุณเลือก
- ตัวช่วย Laravel (สำหรับ Laravel 6.0 ขึ้นไป)—หลังจากติดตั้ง Laravel และ Passport แล้ว ให้เรียกใช้:
composer require laravel/helpers ด้วยการติดตั้งข้างต้น เราก็พร้อมที่จะเริ่มต้น ตรวจสอบให้แน่ใจว่าได้ตั้งค่าการเชื่อมต่อฐานข้อมูลของคุณโดยแก้ไขไฟล์ . .env
บทช่วยสอน Laravel Passport ขั้นตอนที่ 1: เพิ่มคอนโทรลเลอร์และโมเดลสำหรับคำขอจำลอง
อันดับแรก เราจะสร้างคอนโทรลเลอร์และโมเดลสำหรับคำขอจำลอง โมเดลนี้จะไม่ค่อยมีประโยชน์อะไรมากนักในบทช่วยสอนนี้ เพียงเพื่อให้แนวคิดเกี่ยวกับข้อมูลที่ตัวควบคุมมีไว้เพื่อจัดการ
ก่อนสร้างโมเดลและคอนโทรลเลอร์ เราต้องสร้างการโยกย้าย ในเทอร์มินัลหรือหน้าต่าง cmd.exe หากคุณใช้ Windows ให้รัน:
php artisan make:migration create_articles_table --create=articles ตอนนี้ ไปที่โฟลเดอร์ database/migrations และเปิดไฟล์ที่มีชื่อคล้ายกับ xxxx_xx_xx_xxxxxx_create_articles_table.php
ในฟังก์ชัน up ของคลาส เราจะเขียนสิ่งนี้:
Schema::create('articles', function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->string('body'); $table->integer('user_id'); $table->timestamps(); }); ต่อไป เราจะสร้างแบบจำลอง Article ในการทำเช่นนั้น ให้เรียกใช้:
php artisan make:model Article จากนั้นเราสร้างคอนโทรลเลอร์ ArticleController โดยเรียกใช้:
php artisan make:controller ArticleController --resource ต่อไป เราจะแก้ไขไฟล์ app/Providers/AppServiceProvider.php และนำเข้าคลาส Illuminate\Support\Facades\Schema โดยเพิ่ม:
use Illuminate\Support\Facades\Schema…ที่ด้านล่างของการนำเข้าที่ด้านบนของไฟล์
จากนั้นในฟังก์ชันการ boot เราจะเขียนว่า
Schema::defaultStringLength(191);หลังจากทั้งหมดนี้ เราสามารถเรียกใช้:
php artisan migrate…เพื่อใช้การย้ายข้อมูลที่เราสร้างไว้ข้างต้น
บทช่วยสอน Laravel Passport, ขั้นตอนที่ 2: สร้างชิ้นส่วนของมิดเดิลแวร์ที่จำเป็น
ในที่นี้ เราจะเพิ่มมิดเดิลแวร์ที่จำเป็นสำหรับ API ในการทำงาน
คำตอบ JSON
ชิ้นแรกที่ต้องการคือมิดเดิลแวร์ ForceJsonResponse ซึ่งจะแปลงการตอบกลับทั้งหมดเป็น JSON โดยอัตโนมัติ
เมื่อต้องการทำสิ่งนี้ ให้เรียกใช้:
php artisan make:middleware ForceJsonResponse และนี่คือฟังก์ชันจัดการของมิดเดิลแวร์นั้นใน App/Http/Middleware/ForceJsonReponse.php :
public function handle($request, Closure $next) { $request->headers->set('Accept', 'application/json'); return $next($request); } ต่อไป เราจะเพิ่มมิดเดิลแวร์ในไฟล์ app/Http/Kernel.php ของเราในอาร์เรย์ $routeMiddleware :
'json.response' => \App\Http\Middleware\ForceJsonResponse::class, จากนั้นเราจะเพิ่มลงในอาร์เรย์ $middleware ในไฟล์เดียวกัน:
\App\Http\Middleware\ForceJsonResponse::class, ที่จะทำให้แน่ใจว่ามิดเดิลแวร์ ForceJsonResponse ทำงานในทุกคำขอ
CORS (การแบ่งปันทรัพยากรข้ามต้นทาง)
เพื่อให้ผู้บริโภคของ Laravel REST API ของเราเข้าถึงได้จากแหล่งอื่น เราต้องตั้งค่า CORS ในการทำเช่นนั้น เราจะสร้างมิดเดิลแวร์ที่เรียกว่า Cors
ในเทอร์มินัลหรือพรอมต์คำสั่ง cd ลงในไดเร็กทอรีรากของโปรเจ็กต์และรัน:
php artisan make:middleware Cors จากนั้นใน app/Http/Middleware/Cors.php ให้เพิ่มรหัสต่อไปนี้:
public function handle($request, Closure $next) { return $next($request) ->header('Access-Control-Allow-Origin', '*') ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS') ->header('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, X-Token-Auth, Authorization'); } ในการโหลดมิดเดิลแวร์ชิ้นนี้ เราจะต้องเพิ่มบรรทัดในอาร์เรย์ $routeMiddleware ของ app/Http/Kernel.php :
'cors' => \App\Http\Middleware\Cors::class, นอกจากนี้ เราจะต้องเพิ่มลงในอาร์เรย์ $middleware เช่นเดียวกับที่เราทำกับมิดเดิลแวร์ก่อนหน้า:
\App\Http\Middleware\Cors::class, หลังจากทำเช่นนั้น เราจะผนวกกลุ่มเส้นทางนี้ต่อท้าย routes/api.php :
Route::group(['middleware' => ['cors', 'json.response']], function () { // ... });เส้นทาง API ทั้งหมดของเราจะเข้าสู่ฟังก์ชันดังกล่าว ดังที่เราจะเห็นด้านล่าง
บทช่วยสอน Laravel Passport, ขั้นตอนที่ 3: สร้างตัวควบคุมการตรวจสอบสิทธิ์ผู้ใช้สำหรับ API
ตอนนี้ เราต้องการสร้างตัวควบคุมการพิสูจน์ตัวตนด้วยฟังก์ชันการ login และการ register
ขั้นแรก เราจะเรียกใช้:
php artisan make:controller Auth/ApiAuthController ตอนนี้เราจะนำเข้าบางคลาสไปยังไฟล์ app/Http/Controllers/Auth/ApiAuthController.php คลาสเหล่านี้จะใช้ในการสร้างฟังก์ชันการ login และการ register เราจะนำเข้าคลาสโดยเพิ่ม:
use App\User; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; use Illuminate\Support\Str;…ไปที่ด้านบนของคอนโทรลเลอร์
ตอนนี้ เพื่อเพิ่มการพิสูจน์ตัวตน Laravel API สำหรับผู้ใช้ของเรา เราจะสร้างฟังก์ชันการ login logout และ register (ลงชื่อสมัครใช้) ในไฟล์เดียวกัน
ฟังก์ชั่นการ register จะมีลักษณะดังนี้:
public function register (Request $request) { $validator = Validator::make($request->all(), [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:6|confirmed', ]); if ($validator->fails()) { return response(['errors'=>$validator->errors()->all()], 422); } $request['password']=Hash::make($request['password']); $request['remember_token'] = Str::random(10); $user = User::create($request->toArray()); $token = $user->createToken('Laravel Password Grant Client')->accessToken; $response = ['token' => $token]; return response($response, 200); } ฟังก์ชันการ login มีลักษณะดังนี้:
public function login (Request $request) { $validator = Validator::make($request->all(), [ 'email' => 'required|string|email|max:255', 'password' => 'required|string|min:6|confirmed', ]); if ($validator->fails()) { return response(['errors'=>$validator->errors()->all()], 422); } $user = User::where('email', $request->email)->first(); if ($user) { if (Hash::check($request->password, $user->password)) { $token = $user->createToken('Laravel Password Grant Client')->accessToken; $response = ['token' => $token]; return response($response, 200); } else { $response = ["message" => "Password mismatch"]; return response($response, 422); } } else { $response = ["message" =>'User does not exist']; return response($response, 422); } } และสุดท้าย ฟังก์ชัน logout :
public function logout (Request $request) { $token = $request->user()->token(); $token->revoke(); $response = ['message' => 'You have been successfully logged out!']; return response($response, 200); } หลังจากนี้ เราจำเป็นต้องเพิ่มฟังก์ชันการ login การ register และ logout ไปยังเส้นทางของเรา กล่าวคือ ภายในกลุ่มเส้นทางที่มีอยู่ใน API แล้ว:
Route::group(['middleware' => ['cors', 'json.response']], function () { // ... // public routes Route::post('/login', 'Auth\ApiAuthController@login')->name('login.api'); Route::post('/register','Auth\ApiAuthController@register')->name('register.api'); Route::post('/logout', 'Auth\ApiAuthController@logout')->name('logout.api'); // ... }); สุดท้ายนี้ เราต้องเพิ่มคุณสมบัติ HasApiToken ให้กับโมเดล User ไปที่ app/User และตรวจสอบให้แน่ใจว่าคุณมี:
use HasApiTokens, Notifiable;… ที่ด้านบนของชั้นเรียน
สิ่งที่เรามีจนถึงตอนนี้…
หากเราเริ่มต้นแอปพลิเคชันเซิร์ฟเวอร์ เช่น เรียกใช้ php artisan serve จากนั้นลองส่งคำขอ GET ไปยังเส้นทาง /api/user เราควรได้รับข้อความ:
{ "message": "Unauthenticated." } เนื่องจากเราไม่ผ่านการตรวจสอบสิทธิ์ในการเข้าถึงเส้นทางนั้น หากต้องการป้องกันบางเส้นทางที่คุณเลือก เราสามารถเพิ่มเส้นทางเหล่านั้นใน routes/api.php หลัง Route::post บรรทัด:
Route::middleware('auth:api')->group(function () { // our routes to be protected will go in here }); ก่อนดำเนินการต่อ เราจะเพิ่มเส้นทางออกจากระบบไปยังมิดเดิลแวร์ auth:api เนื่องจาก Laravel ใช้โทเค็นเพื่อล็อกผู้ใช้ออก ซึ่งเป็นโทเค็นที่ไม่สามารถเข้าถึงได้จากภายนอกมิดเดิลแวร์ auth:api เส้นทาง สาธารณะ ของเรามีลักษณะดังนี้:
Route::group(['middleware' => ['cors', 'json.response']], function () { // ... // public routes Route::post('/login', 'Auth\ApiAuthController@login')->name('login.api'); Route::post('/register', 'Auth\ApiAuthController@register')->name('register.api'); // ... });เส้นทางที่ ได้รับการคุ้มครอง ของเรามีลักษณะดังนี้:
Route::middleware('auth:api')->group(function () { // our routes to be protected will go in here Route::post('/logout', 'Auth\ApiAuthController@logout')->name('logout.api'); }); ตอนนี้เราจะไปที่ ArticleController ที่เราสร้างขึ้นใน app/Http/Controllers/ArticleController.php และลบวิธีการ create และ edit ในคลาสนั้น หลังจากนั้น เราจะเพิ่มโค้ดต่อไปนี้ ซึ่งแก้ไขเล็กน้อย ในแต่ละฟังก์ชันที่เหลือ:
$response = ['message' => '<function name> function']; return response($response, 200); เราจะกรอก <function name> ตามความเหมาะสม ตัวอย่างเช่น ฟังก์ชั่นการ update จะมีสิ่งนี้เป็นเนื้อหา:
$response = ['message' => 'update function']; return response($response, 200);การทดสอบการตรวจสอบสิทธิ์ Laravel ด้วยตนเอง: การสร้างผู้ใช้
ในการลงทะเบียนผู้ใช้ เราจะส่งคำขอ POST ไปที่ /api/register ด้วยพารามิเตอร์ต่อไปนี้: name , email (ซึ่งต้องไม่ซ้ำกัน), password และ password_confirmation
เมื่อสร้างผู้ใช้แล้ว API จะส่งคืนโทเค็น ซึ่งเราจะใช้ในคำขอเพิ่มเติมเป็นวิธีการตรวจสอบสิทธิ์ของเรา
ในการเข้าสู่ระบบ เราจะส่งคำขอ POST ไปที่ /api/login หากข้อมูลประจำตัวของเราถูกต้อง เราก็จะได้รับโทเค็นจาก API การเข้าสู่ระบบ Laravel ด้วยวิธีนี้
โทเค็นการอนุญาตที่เราได้รับจากคำขอนี้ เราสามารถใช้เมื่อเราต้องการเข้าถึงเส้นทางที่มีการป้องกัน ในบุรุษไปรษณีย์ แท็บ "การอนุญาต" มีเมนูแบบเลื่อนลงซึ่งสามารถตั้งค่าประเภทเป็น "Bearer Token" หลังจากที่โทเค็นสามารถเข้าไปในช่องโทเค็นได้
กระบวนการนี้ค่อนข้างคล้ายกันในการนอนไม่หลับ
ผู้ใช้ cURL สามารถทำสิ่งที่คล้ายกันได้โดยส่งพารามิเตอร์ -H "Authorization: Bearer <token>" โดยที่ <token> เป็นโทเค็นการให้สิทธิ์ที่ได้รับจากการเข้าสู่ระบบหรือการลงทะเบียนตอบกลับ
เช่นเดียวกับ cURL หากนักพัฒนาวางแผนที่จะใช้ API โดยใช้ axios หรือไลบรารีประเภทนั้น พวกเขาสามารถเพิ่มส่วนหัว Authorization ด้วยค่า Bearer <token>
บทช่วยสอน Laravel Passport, ขั้นตอนที่ 4: สร้างฟังก์ชันการรีเซ็ตรหัสผ่าน
เมื่อการรับรองความถูกต้องพื้นฐานเสร็จสิ้นแล้ว ก็ถึงเวลาตั้งค่าฟังก์ชันรีเซ็ตรหัสผ่าน
ในการทำเช่นนี้ เราสามารถเลือกที่จะสร้างไดเร็กทอรีตัวควบคุม api_auth สร้างตัวควบคุมแบบกำหนดเองใหม่ และใช้ฟังก์ชันนี้ หรือเราสามารถแก้ไขตัวควบคุมการตรวจสอบสิทธิ์ที่เราสามารถสร้างด้วย Laravel ได้ ในกรณีนี้ เราจะแก้ไขตัวควบคุมการตรวจสอบสิทธิ์ เนื่องจากแอปพลิเคชันทั้งหมดเป็น API

ขั้นแรก เราจะสร้างตัวควบคุมการตรวจสอบสิทธิ์โดยเรียกใช้:
composer require laravel/ui php artisan ui vue --auth เราจะแก้ไขคลาสใน app/Http/Controllers/Auth/ForgotPasswordController.php เพิ่มสองวิธีนี้:
protected function sendResetLinkResponse(Request $request, $response) { $response = ['message' => "Password reset email sent"]; return response($response, 200); } protected function sendResetLinkFailedResponse(Request $request, $response) { $response = "Email could not be sent to this email address"; return response($response, 500); } ต่อไป เราต้องตั้งค่าตัวควบคุมที่รีเซ็ตรหัสผ่านจริง ดังนั้นเราจะไปที่ app/Http/Controllers/Auth/ResetPasswordController.php และแทนที่ฟังก์ชันเริ่มต้นดังนี้:
protected function resetPassword($user, $password) { $user->password = Hash::make($password); $user->save(); event(new PasswordReset($user)); } protected function sendResetResponse(Request $request, $response) { $response = ['message' => "Password reset successful"]; return response($response, 200); } protected function sendResetFailedResponse(Request $request, $response) { $response = "Token Invalid"; return response($response, 401); }นอกจากนี้เรายังต้องนำเข้าบางคลาสในคอนโทรลเลอร์โดยเพิ่ม:
use Illuminate\Auth\Events\PasswordReset; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash;…ไปที่ด้านบนของคอนโทรลเลอร์
เราต้องการแก้ไขว่าจะใช้การแจ้งเตือนทางอีเมลใดบ้าง เนื่องจากการแจ้งเตือนอีเมลที่มาพร้อมกับ Laravel ไม่ได้ใช้โทเค็น API สำหรับการให้สิทธิ์ เราสามารถสร้างใหม่ได้ภายใต้ app/Notifications โดยเรียกใช้คำสั่งนี้:
php artisan make:notification MailResetPasswordNotification เราจำเป็นต้องแก้ไขไฟล์ app/Notifications/MailResetPasswordNotification.php เพื่อให้มีลักษณะดังนี้:
<?php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Auth\Notifications\ResetPassword; use Illuminate\Support\Facades\Lang; class MailResetPasswordNotification extends ResetPassword { use Queueable; protected $pageUrl; public $token; /** * Create a new notification instance. * * @param $token */ public function __construct($token) { parent::__construct($token); $this->pageUrl = 'localhost:8080'; // we can set whatever we want here, or use .env to set environmental variables } /** * Get the notification's delivery channels. * * @param mixed $notifiable * @return array */ public function via($notifiable) { return ['mail']; } /** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ public function toMail($notifiable) { if (static::$toMailCallback) { return call_user_func(static::$toMailCallback, $notifiable, $this->token); } return (new MailMessage) ->subject(Lang::getFromJson('Reset application Password')) ->line(Lang::getFromJson('You are receiving this email because we received a password reset request for your account.')) ->action(Lang::getFromJson('Reset Password'), $this->pageUrl."?token=".$this->token) ->line(Lang::getFromJson('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.users.expire')])) ->line(Lang::getFromJson('If you did not request a password reset, no further action is required.')); } /** * Get the array representation of the notification. * * @param mixed $notifiable * @return array */ public function toArray($notifiable) { return [ // ]; } } เพื่อใช้ประโยชน์จากการแจ้งเตือนใหม่นี้ เราจำเป็น Authenticatable แทนที่เมธอด sendPasswordResetNotification ที่ User รับช่วงมาจากคลาส สิ่งที่เราต้องทำคือเพิ่มสิ่งนี้ใน app/User.php :
public function sendPasswordResetNotification($token) { $this->notify(new \App\Notifications\MailResetPasswordNotification($token)); }ด้วยการตั้งค่าเมลที่ทำงานอย่างถูกต้อง การแจ้งเตือนควรจะทำงาน ณ จุดนี้
สิ่งที่เหลืออยู่ตอนนี้คือการควบคุมการเข้าถึงของผู้ใช้
บทช่วยสอน Laravel Passport, ขั้นตอนที่ 5: สร้างมิดเดิลแวร์การควบคุมการเข้าถึง
ก่อนที่เราจะสร้างมิดเดิลแวร์การควบคุมการเข้าถึง เราจะต้องอัปเดตตาราง user ให้มีคอลัมน์ชื่อ type ซึ่งจะใช้เพื่อกำหนดระดับผู้ใช้: ประเภท 0 คือผู้ใช้ปกติ ประเภทที่ 1 คือผู้ดูแลระบบ และประเภทที่ 2 คือ ผู้ดูแลระบบขั้นสูง
ในการอัปเดตตาราง user เราต้องสร้างการโยกย้ายโดยเรียกใช้สิ่งนี้:
php artisan make:migration update_users_table_to_include_type --table=users ในไฟล์ที่สร้างใหม่ของรูปแบบ database/migrations/[timestamp]_update_users_table.php เราจะต้องอัปเดตฟังก์ชัน up และ down เพื่อเพิ่มและลบคอลัมน์ type ตามลำดับ:
public function up() { Schema::table('users', function (Blueprint $table) { $table->integer('type'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { $table->dropIfExists('type'); }); } ต่อไป เราจะเรียกใช้ php artisan migrate เมื่อเสร็จแล้ว เราต้องแก้ไขฟังก์ชั่นการ register ของเราในไฟล์ ApiAuthController.php โดยเพิ่มสิ่งนี้ก่อนบรรทัดด้วย $user = User::create($request->toArray()); :
$request['type'] = $request['type'] ? $request['type'] : 0; นอกจากนี้ เราจะต้องเพิ่มบรรทัดนี้ในอาร์เรย์ $validator :
'type' => 'integer',การแก้ไขครั้งแรกของทั้งสองอย่างนี้จะทำให้ผู้ใช้ที่ลงทะเบียนทั้งหมดเป็น "ผู้ใช้ปกติ" โดยค่าเริ่มต้น กล่าวคือ ถ้าไม่ได้ป้อนประเภทผู้ใช้
มิดเดิลแวร์การควบคุมการเข้าถึง
ตอนนี้เราอยู่ในฐานะที่จะสร้างมิดเดิลแวร์สองชิ้นเพื่อใช้ในการควบคุมการเข้าถึง: อันหนึ่งสำหรับผู้ดูแลระบบและอีกอันสำหรับผู้ดูแลระบบระดับสูง
ดังนั้นเราจะดำเนินการ:
php artisan make:middleware AdminAuth php artisan make:middleware SuperAdminAuth ก่อนอื่น เราจะไปที่ app/Http/Middleware/AdminAuth.php และนำเข้า Illuminate\Support\Facades\Auth จากนั้นแก้ไขฟังก์ชันการ handle ดังนี้:
public function handle($request, Closure $next) { if (Auth::guard('api')->check() && $request->user()->type >= 1) { return $next($request); } else { $message = ["message" => "Permission Denied"]; return response($message, 401); } } เราจะต้องแก้ไขฟังก์ชันการ handle ใน app/Http/Middleware/SuperAdminAuth.php :
public function handle($request, Closure $next) { if (Auth::guard('api')->check() && $request->user()->type >= 2) { return $next($request); } else { $message = ["message" => "Permission Denied"]; return response($message, 401); } } คุณควรนำเข้าคลาส Auth ที่ด้านบนของทั้งสองไฟล์โดยเพิ่ม:
use Illuminate\Support\Facades\Auth;…ที่ด้านล่างของการนำเข้าที่พบที่นั่น
เพื่อที่จะใช้มิดเดิลแวร์ใหม่ของเรา เราจะอ้างอิงทั้งสองคลาสในเคอร์เนล—เช่น ใน app/Http/Kernel.php — โดยเพิ่มบรรทัดต่อไปนี้ในอาร์เรย์ $routeMiddleware :
'api.admin' => \App\Http\Middleware\AdminAuth::class, 'api.superAdmin' => \App\Http\Middleware\SuperAdminAuth::class,หากนักพัฒนาต้องการใช้มิดเดิลแวร์ในเส้นทางที่กำหนด สิ่งที่คุณต้องทำคือเพิ่มไปยังฟังก์ชันเส้นทางดังนี้:
Route::post('route','Controller@method')->middleware('<middleware-name-here>'); <middleware-name-here> ในกรณีนี้สามารถเป็น api.admin , api.superAdmin ฯลฯ ตามความเหมาะสม
นั่นคือทั้งหมดที่จำเป็นในการสร้างมิดเดิลแวร์ของเรา
วางมันทั้งหมดเข้าด้วยกัน
เพื่อทดสอบว่าการรับรองความถูกต้องและการควบคุมการเข้าถึงของเราทำงาน มีขั้นตอนเพิ่มเติมบางอย่างที่ต้องดำเนินการ
การทดสอบ Laravel Authentication และ Access Control: ขั้นตอนที่ 1
เราจำเป็นต้องแก้ไขฟังก์ชัน index ของ ArticleController และลงทะเบียนเส้นทาง (ในโครงการจริง เราจะใช้ PHPUnit และทำสิ่งนี้เป็นส่วนหนึ่งของการทดสอบอัตโนมัติ ที่นี่ เรากำลังเพิ่มเส้นทางด้วยตนเองเพื่อวัตถุประสงค์ในการทดสอบ—สามารถนำออกได้ในภายหลัง)
เราจะไปที่ตัวควบคุม ArticleController ที่ app/Http/Controllers/ArticleController และแก้ไขฟังก์ชัน index ให้มีลักษณะดังนี้:
public function index() { $response = ['message' => 'article index']; return response($response, 200); } ต่อไป เราจะลงทะเบียนฟังก์ชันในเส้นทางโดยไปที่ไฟล์ routes/api.php และต่อท้ายสิ่งนี้:
Route::middleware('auth:api')->group(function () { Route::get('/articles', 'ArticleController@index')->name('articles'); });การทดสอบ Laravel Authentication และ Access Control: ขั้นตอนที่ 2
ตอนนี้เราสามารถลองเข้าถึงเส้นทางโดยไม่ต้องใช้โทเค็นการพิสูจน์ตัวตน เราควรได้รับข้อผิดพลาดในการตรวจสอบสิทธิ์
การทดสอบ Laravel Authentication และ Access Control: ขั้นตอนที่ 3
นอกจากนี้เรายังสามารถพยายามเข้าถึงเส้นทางเดียวกันด้วยโทเค็นการให้สิทธิ์ (อันที่เราได้รับจากการลงทะเบียนหรือเข้าสู่ระบบในตอนต้นของบทความนี้)
บางครั้ง การทำเช่นนี้อาจทำให้เกิดข้อผิดพลาดในลักษณะนี้:
Unknown column 'api_token' in 'where clause' (SQL: select * from `users` where `api_token` = ... หากสิ่งนี้เกิดขึ้น นักพัฒนาควรตรวจสอบให้แน่ใจว่าได้เรียกใช้การโยกย้าย Passport และตั้งค่า ['guards']['api']['driver'] เป็น passport ใน config/auth.php :
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ],หลังจากนั้น แคชการกำหนดค่าจำเป็นต้องอัปเดตเช่นกัน
เมื่อแก้ไขแล้วเราควรเข้าถึงเส้นทางได้
การทดสอบ Laravel Authentication และ Access Control: ขั้นตอนที่ 4
ได้เวลาทดสอบการควบคุมการเข้าถึงแล้ว มาผนวก ->middleware('api.admin') ต่อท้ายเส้นทางของบทความ หน้าตาจะเป็นดังนี้:
Route::get('/articles', 'ArticleController@index')->middleware('api.admin')->name('articles'); เราทำให้ผู้ใช้ที่สร้างขึ้นใหม่ได้รับการกำหนดประเภท 0 โดยอัตโนมัติ ตามที่เราเห็นผ่านเส้นทาง api/user
ด้วยเหตุนี้ เราจึงควรได้รับข้อผิดพลาดขณะพยายามเข้าถึงจุดสิ้นสุดของ articles ในฐานะผู้ใช้ดังกล่าว
เพื่อวัตถุประสงค์ในการทดสอบ เรามาแก้ไขผู้ใช้ในฐานข้อมูลให้เป็น type 1 หลังจากตรวจสอบการเปลี่ยนแปลงนั้นผ่านเส้นทาง api/user อีกครั้ง เราก็พร้อมที่จะลองอีกครั้งเพื่อ GET เส้นทาง /articles/
มันทำงานได้อย่างสมบูรณ์
นักพัฒนาที่สร้างแอปพลิเคชันที่ซับซ้อนมากขึ้นควรสังเกตว่าการควบคุมการเข้าถึงที่เหมาะสมจะไม่ง่ายเช่นนี้ ในกรณีดังกล่าว สามารถใช้แอปพลิเคชันบุคคลที่สามอื่นๆ หรือเกทและนโยบายของ Laravel เพื่อใช้การควบคุมการเข้าถึงของผู้ใช้แบบกำหนดเองได้ ในส่วนที่สองของชุดนี้ เราจะพิจารณาโซลูชันการควบคุมการเข้าใช้ที่มีประสิทธิภาพและยืดหยุ่นมากขึ้น
การตรวจสอบสิทธิ์ Laravel API: สิ่งที่เราได้เรียนรู้
ในบทช่วยสอน Laravel Passport นี้ เราได้พูดถึง:
- การสร้าง dummy controller และ model เพื่อให้มีบางสิ่งที่จะใช้ขณะทดสอบตัวอย่าง Laravel Passport ของเรา
- การสร้างมิดเดิลแวร์ที่จำเป็นในการทำให้ API ของเราทำงานได้อย่างราบรื่น โดยระบุถึง CORS และบังคับให้ API ส่งคืนการตอบสนอง JSON เสมอ
- การตั้งค่าการพิสูจน์ตัวตน Laravel API พื้นฐาน: การลงทะเบียน การเข้าสู่ระบบ และการออกจากระบบ
- การตั้งค่าฟังก์ชัน "รีเซ็ตรหัสผ่าน" ตามค่าเริ่มต้นของ Laravel
- การสร้างมิดเดิลแวร์การควบคุมการเข้าถึงเพื่อเพิ่มระดับการอนุญาตผู้ใช้ไปยังเส้นทางต่างๆ
ทักษะเหล่านี้เป็นทักษะที่จำเป็นสำหรับทุกคนที่ทำงานในสายงานบริการพัฒนา Laravel ผู้อ่านจะพบผลลัพธ์สุดท้ายใน repo GitHub นี้ และตอนนี้ควรอยู่ในตำแหน่งที่ดีในการปรับใช้การรับรองความถูกต้องด้วย Laravel เราหวังว่าจะแสดงความคิดเห็นด้านล่าง
