Menu

Saturday, April 7, 2018

[Laravel - Package] การสร้าง Refresh Token เองจาก jwt-auth version 1.0.0-rc.1
[Laravel - Package] How to Manually Generate Refresh Token from jwt-auth version 1.0.0-rc.1

tymon/jwt-auth เป็น library สำหรับจัดการการเข้าใช้งานแบบ token โดยเวอร์ชั่นล่าสุดในตอนนี้ คือ 1.0.0-rc.1

สำหรับ access token สามารถสร้าง, ตรวจสอบและใช้งานได้อย่างปกติ แต่สำหรับการ refresh token นั้นจะผิดแปลกไปจาก library สำหรับ JWT ทั่วไป

โดยทั่วไปแล้ว หลังจากที่เรา refresh token ไปแล้ว เราจะได้ access token ใหม่ที่เริ่มนับเวลาหมดอายุรวมถึงเวลาที่สามารถทำการ refresh ใหม่ด้วย เพื่อใช้ token นั้นในระบบต่อไป โดยที่ระบบจะบังคับให้เรา login ใหม่ก็ต่อเมื่อเราไม่ได้ใช้งานระบบเป็นเวลานานจน access token หมดอายุและเลยกำหนดเวลาที่จะ refresh token ได้

สำหรับการ refresh token ของ jwt-auth นั้น access token ใหม่จะเริ่มนับเวลาหมดอายุใหม่เท่านั้น แต่เวลาที่สามารถทำการ refresh ใหม่นั้น ยังคงนับเวลาต่อจากเวลาของ token เดิม เนื่องจากเวลาสร้างของ access token ใหม่ใช้เวลาสร้างเดียวกับ access token เดิม ทำให้ไม่ว่าเราจะ refresh token ไปกี่ครั้ง ระบบก็จะบังคับให้เรา login ใหม่ เมื่อ access token ปัจจุบันหมดอายุและเลยกำหนดเวลาที่จะ refresh token ตัวแรกที่ได้หลังจาก log in ได้


เพื่อให้เห็นภาพ สมมติว่า เราตั้งเวลาให้ access token หมดอายุหลังจาก 1 นาที เวลาที่สามารถ refresh  token ได้เป็น 2 นาที เรา login และได้ access token ตัวแรกที่นาทีที่ 0 เมื่อเราใช้งานไปสักพักถึงนาทีที่ 1.1 token หมดอายุ ระบบทำการ refresh token ได้ตามปกติ แล้วเราก็ใช้งาน token ตัวใหม่ต่อไปจนถึงนาทีที่ 2.1 token หมดอายุ ระบบทำการ refresh token จะได้ error กลับมาว่า token นั้นหมดอายุแล้ว เนื่องจากเลยกำหนดเวลาที่สามารถ refresh token ได้ (เลย 2 นาทีนับจาก log in ครั้งแรก)

ใน config/jwt.php ได้เขียนอธิบายไว้ดังนี้
| Refresh time to live
    |--------------------------------------------------------------------------
    |
    | Specify the length of time (in minutes) that the token can be refreshed
    | within. I.E. The user can refresh their token within a 2 week window of
    | the original token being created until they must re-authenticate.
    | Defaults to 2 weeks
    |
จากคำอธิบายของ library จะเห็นว่า ระยะเวลาที่สามารถ refresh token ได้จะตั้งไว้เป็นเวลานานมาก และเป็นการตั้งเวลาเพื่อบังคับให้ login ใหม่ ซึ่งการตั้งเวลาเช่นนี้เป็นการตั้งเวลาที่แตกต่างไปจาก JWT library ทั่วไปมากและอาจจะส่งผลถึงเรื่อง security ด้วย

ดังนั้น เราจำเป็นจะต้องแก้ไขเวลาสร้างของ access token ใหม่เอง เพื่อที่จะได้ลดช่วงเวลาสำหรับ refresh token ลงและให้ผู้ใช้สามารถใช้งานได้เรื่อยๆจนกว่าจะไม่ได้ใช้ระบบเป็นเวลานาน จึงให้ log in ใหม่อีกครั้ง

โค้ดที่แก้ไขเป็นตามด้านล่างนี้
use JWTAuth; 
...
$token = $request->header('Authorization');
...
JWTAuth::setToken($token);
$new_token = JWTAuth::refresh();
JWTAuth::setToken($new_token);
$payload = JWTAuth::decode(JWTAuth::getToken()); // Tymon\JWTAuth\Payload
$claims = $payload->getClaims(); // Tymon\JWTAuth\Claims\Collection
$iat = $claims->getByClaimName('iat'); // Tymon\JWTAuth\Claims\IssuedAt
$iat->setValue(time());
$new_token = JWTAuth::encode($payload); // Tymon\JWTAuth\Token
$new_token = $new_token->get(); // string

No comments:

Post a Comment