Menu

Monday, August 5, 2019

[Laravel - Package] วิธีการเปลี่ยนข้อมูลที่ใช้สำหรับ Subject Claim ของ JWT ใน Laravel Model
[Laravel - Package] How to Change Data for Subject Claim of JWT in Laravel Model

JSON Web Token (JWT) ถูกใช้ใน stateless web application

jwt-auth เป็น JWT package ที่นิยมใช้สำหรับ Laravel framework

package นี้จะใช้ ID ของผู้ใช้งานเป็น sub claim (subject claim) โดยอัตโนมัติ

เนื่องจาก payload ของ JWT สามารถ decode ที่ใดก็ได้ โดยไม่จำเป็นต้องใช้ key ใดๆ การใช้ ID ของผู้ใช้งาน จึงทำให้เกิดปัญหาทางด้านความปลอดภัย

คุณสามารถเปลี่ยนฟิลด์ ID ของผู้ใช้งานเป็นฟิลด์อื่นด้วยวิธีตามด้านล่างนี้ เพื่อหลีกเลี่ยงปัญาด้านความปลอดภัย
สมมติว่า User model extend Illuminate\Foundation\Auth\User และ implement Tymon\JWTAuth\Contracts\JWTSubject 

ขั้นแรก คุณต้องใช้ฟิลด์ email หรือ unique field อื่นๆ เป็น sub claim ของ JWT แทนฟิลด์ id โดยเพิ่ม function ข้างล่างนี้ใน User model
public function getJWTIdentifier() { 
    return $this->email; 
}
หมายเหตุ: คุณสามารถ decode token ที่ถูกสร้างขึ้นได้ที่ jwt.io เพื่อตรวจสอบ payload ของ JWT

อย่างไรก็ตาม token นี้ยังไม่สามารถใช้เป็น access token ได้

หลังจากที่ token ถูก parse แล้ว Laravel จะใช้ค่าของ sub claim ในการเปรียบเทียบกับฟิลด์ที่ใช้ระบุตัวตนของผู้ใช้งาน ซึ่งยังคงเป็นฟิลด์ id 

ดังนั้น เราต้องเปลี่ยนฟิลด์ที่ใช้ระบุตัวตนของ user เป็นฟิลด์เดียวกันกับ sub claim โดยเพิ่ม function ข้างล่างนี้ใน User model
public function getAuthIdentifierName() {
    return 'email'; 
}
อย่างไรก็ตามการ override getAuthIdentifierName function มีผลกระทบกับ auth helper function และ Auth facade class เนื่องจากทั้ง auth()->id() และ Auth::id() เรียกใช้ getAuthIdentifier function เพื่อดึงค่าที่ใช้ระบุตัวตนของผู้ใช้งาน และโดยปกติแล้ว getAuthIdentifier function จะเรียกใช้ getAuthIdentifierName function อีกที เพื่อดึงค่าฟิลด์ที่ต้องใช้ตามข้างล่างนี้
public function getAuthIdentifier() { 
    return $this->{$this->getAuthIdentifierName()}; 
}

เพราะฉะนั้นทั้ง auth()->id() และ Auth::id() จะได้ค่าเป็น email ของ user แทน id ของผู้ใช้งาน

อย่างไรก็ตาม คุณอาจจะอยากใช้ฟิลด์ id เป็นฟิลด์ที่ใช้ระบุตัวตนของผู้ใช้งานสำหรับทุกกรณี ยกเว้นตอน authentication เท่านั้น
หมายเหตุ:  บาง package มีการเรียก auth()->id เพื่อเก็บค่าเป็น reference key ของผู้ใช้งานในตาราง user ใน database

ดังนั้น คุณต้อง override getAuthIdentifier function โดยเพิ่ม function ข้างล่างนี้ใน User model
public function getAuthIdentifier() {
    return $this->id; 
}

No comments:

Post a Comment