By Arnon Puitrakul - 30 กรกฎาคม 2016
ผมเชื่อว่า ใครที่พึ่งเริ่มเรียน หรือหัดใช้ Laravel สิ่ง ๆ หนึ่งที่พวกเราหลาย ๆ คนไม่น่าอยากเข้าไปยุ่งในตอนนั้นคือ Middleware มันดูเป็นอะไรที่ ลึกลับ ซับซ้อน มาก ๆ สำหรับผมตอนแรก ๆ เลย แต่พอเราได้ลองมาดูจริง ๆ แล้ว มันแค่หลอกตาเราเท่านั้นแหละ ง่ายมาก ๆ เลย วันนี้เราจะลองมาดูกันว่า มันคืออะไร และ ทำอะไรได้บ้าง
ผมก็ไม่รู้จะนิยามมันว่ายังไงเหมือนกัน อธิบายให้มนุษย์เข้าใจ มันคือ ตัวกรอง ในเครื่องกรองน้ำเลย ในที่นี้มันทำหน้าที่ในการกรอง Request ต่าง ๆ ที่ User กดไป กดมา อยู่ใน App ของเรา
เราลองมาดูการทำงานแบบผิว ๆ กัน ก่อนที่เราจะเข้าไปดูว่าโค๊ตจริง ๆ นั้นเป็นอย่างไร
ให้เรานึกภาพว่า Middleware แต่ละชั้นคือ ชั้นของหัวหอม, ปลายทางคือ ชั้นในสุด ของหัวหอมละกัน และตัวเราเป็น เข็ม ที่เจาะเข้าไป
วิธีการทำงานของมันนั้นง่ายมาก ๆ ถ้าเราต้องการเข้าไปหา ชั้นในสุด เราก็ต้องเจาะจากข้างนอกเรื่อย ๆ หรือก็คือ การผ่าน Middleware ไปทีละชั้นนั่นเอง ซึ่งในตัวมันเองก็จะมี Logic เพื่อเช็คเงื่อนไขต่าง ๆ ก็ว่าไป ตามสิ่งที่มันต้องทำ
ตัวอย่างเช่น Auth ที่ Laravel เตรียมมาให้ หน้าที่ของมันนั้นเรียบง่ายมาก แค่เช็คว่า User Login หรือยัง ถ้า Login แล้วก็ให้ผ่านไปที่ Middleware ตัวต่อไป ถ้ายัง ก็ให้โยนไปหน้า Login เท่านั้นเลย
Middleware จะอาศัยอยู่ใน App/Http/Middleware ถ้าเราเข้าไป เราจะเห็นไฟล์อยู่ 4 ไฟล์ พวกนั้นก็คือ Middleware ที่ Laravel นั้นเตรียมมาให้
หลัก ๆ แล้ว ส่วนการทำงานของ Middleware นั้นจะมีอยู่แค่ส่วนเดียวนั้นก็คือ Method ชื่อว่า handle
ถ้าเราลองเข้าไปดู Authenticate Middleware เราจะเห็นว่าใน Class นั้นมี handle Method อยู่แค่อันเดียวเท่านั้น
สิ่งที่มันรับเข้ามาคือ Request ค่าต่าง ๆ ที่ถูกส่งเข้ามา อันนี้น่าจะรู้อยู่แล้ว และ Closure ที่ทำหน้าที่เป็นเหมือน Stack ที่จะบอกว่า หอมชั้นต่อไปคือใครนั่นเอง
ฉะนั้นการเราในบรรทัดสุดท้าย ที่ใน Code เขียนว่า
return $next($request);
มันคือการโยนค่าไปที่หัวหอม หรือ Middleware ชั้นต่อไปนั่นเอง ส่วนที่เหลือ ก็จะเป็น Logic ต่าง ๆ ก็ว่ากันไปว่าจะทำอะไร อยู่ที่ Middleware ตัวนั้น ๆ
อยู่ ๆ การที่เราสร้างไฟล์แล้วเขียนขึ้นมาดื้อ ๆ เลยก็ไม่ได้ มันจะไม่ทำงาน วิธีคือ เราจะต้องทำการ Register มันก่อน เหมือนเป็นการบอกว่า เราจะใช้ Middleware ตัวไหนบ้าง
ซึ่งการ Register นั้นง่ายมาก ๆ เพียงแค่เราเข้าไปเติมบอกมันในไฟล์ Kernel.php ที่อยู่ใน App/Http เมื่อเราเข้ามาในไฟล์แล้ว อยากให้สนใจที่ Array 3 ตัว มันจะต่างกัน ยังไง ลองไปทีละดูกัน
ตัวแรก เราเรียกมันว่า Global Middleware เป็นส่วนที่บอก Laravel ว่า ก่อนจะเรียก Request ทุกอย่าง จะต้องผ่าน Middleware พวกนี้เสมอ ซึ่งเราก็สามารถสร้าง แล้วเอามาเติมได้เช่นกัน
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
];
ตัวถัดไป เราเรียกมันว่า Middleware Group เป็นการแยกกันเลยว่า ถ้า Request ที่เรียกมานั้นเป็น Web ให้มันรันอะไรบ้าง และถ้าเป็น API ให้รันอะไรบ้างก็เติมลงไปในนี้ได้เลย เช่น StartSession ที่เป็นการเปิด Session เวลาเราเรียก API เราไม่จำเป็นต้องใช้ ฉะนั้นบนฝั่งของ API ก็ไม่จำเป็นต้องเรียกเปิดนั่นเอง
พูดง่าย ๆ คือ มันจะแบ่งออกเป็น 2 ส่วนคือ ส่วนที่ Web จะต้องเรียกเสมอ และอีกส่วนคือส่วนที่ API จะต้องเรียกเสมอ แยกกัน
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
],
];
และสุดท้ายคือ Route Middleware ตัวนี้ไม่ใช่ว่า เรา Register มันในนี้แล้วจะใช้ได้ทันทีนะ ถ้าเราจะใช้ เราต้องเข้าไปกำหนดใน Route ด้วยว่า เราจะใช้นะ เราถึงต้องกำหนดชื่อให้มันนั่นเองเช่น auth ที่เป็นการเช็คในเรื่องของ Authenticate ต่าง ๆ เป็นต้น
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
ซึ่งวิธีการใช้นั้นง่ายมาก ๆ สมมุติว่า เรามี Route ที่หน้าแรกละกัน แล้วเราต้องการใช้ auth เราก็แค่สั่งไปว่า
Route::get('/'['middleware' => 'auth', 'uses' => function(){
});
แค่นี้เลย ก่อนที่มันจะเข้าไปเรียก Function ใน Route มันก็จะเข้าไปใน auth ก่อนนั่นเอง
หรืออีกวิธี เราสามารถควบคุมในระดับ Controller ได้ด้วย โดยการไปใส่ไว้ใน Constructor ของ Controller นั้น ๆ ได้ด้วย
ถ้าเรารู้จัก Constructor มันคือ Method แรกที่จะถูกเรียกทุกครั้งเวลาเราสร้าง Object จาก Class นั้น ๆ ฉะนั้นถ้าเราเอาไปใส่ไว้ในนั้นก็เป็นเหมือนกับการบังคับเรียกทุกครั้งที่เราเข้าถึง Controller ตัวนั้น ๆ นั่นเอง เช่น
public function __construct()
{
$this->middleware('auth');
}
เขียนมาอาจจะ งง ว่ามันเกี่ยวกันยังไง หรือว่า มันจะเรียกอันไหนบ้าง สรุปคือ Laravel มันจะเรียกทุกชนิดเลย ตามประเภทของ Request ที่เข้ามา
นอกจากที่เราจะใช้จากที่ Laravel ให้เรามาแล้ว เราสามารถที่จะสร้างมันขึ้นมาใช้เองได้้ด้วยวิธีคือ เรียกคำสั่งด้านล่างนี้ใน Command Line ได้เลย
php artisan make:middleware ชื่ออะไรก็แล้วแต่
เราก็จะได้ไฟล์ตัวนึงขึ้นมา เราก็เขียน Logic ที่เราต้องการลงใน handle method ได้เลย และสุดท้าย ห้ามลืม ต้องไป Register ลงใน Kernel ด้วย ไม่งั้นมันจะไม่รันนะ
ในบทความนี้อาจจะไม่ได้ลงลึกอะไรมากเท่าไหร่ แต่ก็เพียงพอที่จะทำให้เราได้ไปรู้จักกับสิ่งเล็ก ๆ ที่เรียกว่า Middleware คร่าว ๆ รวม ๆ แล้วมันเป็น ตัวกรอง Request ต่าง ๆ ที่เข้ามา ผ่านเข้าไปทีละชั้น ๆ เรื่อย ๆ เหมือนหัวหอม
โดยเราสามารถสร้างมันขึ้นมา และเขียน Logic ต่าง ๆ ลงไปตามที่เราต้องการได้เลยเหมาะสำหรับ สิ่งที่เราต้องการจะเรียกก่อนที่จะให้ Controller เริ่มทำงาน อาจจะเป็นการตรวจสอบ หรือ การทำงานต่าง ๆ ก็ว่ากันไปตามที่ใจต้องการ
โพสต์นี้ก็เขียนไม่ยาวมาก เพราะเราไม่ได้เจาะลึกอะไร แต่ถ้าอยากให้เขียนเจาะลึกก็ Comment เข้ามา เดี๋ยวจะเขียนให้อ่านกัน หรือ ถ้าใครมีคำถามอะไรสงสัยสามารถ Comment ด้านล่างได้เลย ไม่กัด ฉีดยาแล้ว เดี๋ยวจะเข้ามาตอบให้นะครับ!
Obsidian เป็นโปรแกรมสำหรับการจด Note ที่เรียกว่า สารพัดประโยชน์มาก ๆ เราสามารถเอามาทำอะไรได้เยอะมาก ๆ หนึ่งในสิ่งที่เราเอามาทำคือ นำมาใช้เป็นระบบสำหรับการจัดการ Todo List ในแต่ละวันของเรา ทำอะไรบ้าง วันนี้เราจะมาเล่าให้อ่านกันว่า เราจัดการะบบอย่างไร...
อะ อะจ๊ะเอ๋ตัวเอง เป็นยังไงบ้างละ เมื่อหลายเดือนก่อน เราไปเล่าเรื่องกันขำ ๆ ว่า ๆ จริง ๆ แล้วพวก Loop ที่เราใช้เขียนโปรแกรมกันอยู่ มันไม่มีอยู่จริง สิ่งที่เราใช้งานกันมันพยายาม Abstract บางอย่างออกไป วันนี้เราจะมาถอดการทำงานของ Loop จริง ๆ กันว่า มันทำงานอย่างไรกันแน่ ผ่านภาษา Assembly...
นอกจากการทำให้ Application รันได้แล้ว อีกเรื่องที่สำคัญไม่แพ้กันคือการวางระบบ Monitoring ที่ดี วันนี้เราจะมาแนะนำวิธีการ Monitor การทำงานของ MySQL ผ่านการสร้าง Dashboard บน Grafana กัน...
จากตอนที่แล้ว เราเล่าในเรื่องของการ Harden Security ของ SSH Service ของเราด้วยการปรับการตั้งค่าบางอย่างเพื่อลด Attack Surface ที่อาจจะเกิดขึ้นได้ หากใครยังไม่ได้อ่านก็ย้อนกลับไปอ่านกันก่อนเด้อ วันนี้เรามาเล่าวิธีการที่มัน Advance มากขึ้น อย่างการใช้ fail2ban...