[Debug] firebase/php-jwt Cannot handle token prior to[timestamp] 的解決過程

起因

在進行公司專案開發時,有使用到LINE Login v2.1的oauth2,在導到callback URL後會在service層打line的
oauth2,但每次登入失敗,log紀錄後看到

1
2
3
4
[2021-03-26 09:34:51] local.ERROR: Line Login Error, JWT decode error
Cannot handle token prior to 2021-03-26T09:34:53+0800

[2021-03-26 09:36:35] local.ERROR: payload->iat = 1616722597 and time() = 1616722595 leeway= 0

payload->iat 是ID token 產生的時間 (UNIX 時間)
time() 是本機產生的時間 (UNIX 時間)
在v5.2.0中的JWT.php中寫道

1
2
3
4
5
6
7
8
// Check that this token has been created before 'now'. This prevents
// using tokens that have been created for later use (and haven't
// correctly used the nbf claim).
if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) {
throw new BeforeValidException(
'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->iat)
);
}

其中他檢查$payload->iat 是否存在以及 $payload->iat的時間是否小於業務系統端的時間
依據上面的數據顯示payload->iat = 1616722597 是大於 time() = 1616722595
而產生此Error
看下來原來是api伺服器的時間與業務系統所在的機器時間有些小偏差所致。

解決方法

查看firebase/php-jwt的原始碼提供了一個靜態變量$leeway,

/**
 * When checking nbf, iat or expiration times,
 * we want to provide some extra leeway time to
 * account for clock skew.
 */
public static $leeway = 0;

我們可以在JWT::decode前加上JWT::$leeway += 2;

來解決問題(視偏差情形 如果太大就不太能使用此方法)

實際上筆者是用mac air來做開發,在重新同步時間後 問題就消失了
以此記錄一下