การตรวจสอบสิทธิ์ผู้ใช้และการควบคุมการเข้าถึงแบบเต็ม – บทช่วยสอน 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 เราหวังว่าจะแสดงความคิดเห็นด้านล่าง