修改Laravel Passport的oauth_access_token.expires_at日期格式遇问题求助
解决Laravel Passport在SQL Server法语环境下expires_at日期格式错误问题
问题原因
虽然通过继承PassportToken并设置$dateFormat解决了created_at和updated_at的格式问题,但expires_at字段的赋值逻辑在Passport内部可能绕过了模型默认的日期转换机制,导致自定义的$dateFormat未生效。
解决方案
1. 确保模型包含expires_at日期字段
确认自定义AccessToken模型中,$dates属性包含expires_at(若重写了$dates则必须显式声明,父模型已定义的话可省略):
namespace App\Models; use Laravel\Passport\Token as PassportToken; class AccessToken extends PassportToken { protected $dateFormat = 'Y-d-m H:i:s.v'; // 若重写$dates,必须包含以下字段 protected $dates = ['created_at', 'updated_at', 'expires_at']; }
2. 重写expires_at字段的存取器
通过自定义setter和getter强制处理日期格式,确保存入和读取时的格式统一:
public function setExpiresAtAttribute($value) { // 将Carbon实例转换为指定格式的字符串存入数据库 if ($value instanceof \Carbon\Carbon) { $this->attributes['expires_at'] = $value->format($this->dateFormat); } else { $this->attributes['expires_at'] = $value; } } public function getExpiresAtAttribute($value) { // 从数据库读取时转换为Carbon实例 return \Carbon\Carbon::createFromFormat($this->dateFormat, $value); }
3. 验证数据库字段类型
确保SQL Server中oauth_access_tokens表的expires_at字段类型为datetime2(而非datetime),因为datetime不支持毫秒级精度,与你指定的.v格式不匹配会导致插入错误。
4. 替换Passport默认的Token模型
在AuthServiceProvider的boot方法中,指定Passport使用自定义的AccessToken模型:
use App\Models\AccessToken; use Laravel\Passport\Passport; public function boot() { $this->registerPolicies(); Passport::routes(); // 绑定自定义Token模型 Passport::useTokenModel(AccessToken::class); }
验证步骤
创建新access_token后,直接查看数据库oauth_access_tokens表的expires_at字段,确认格式为Y-d-m H:i:s.v;同时在应用中尝试读取该字段,验证是否能正常转换为Carbon实例,避免后续使用时出现日期解析错误。
内容的提问来源于stack exchange,提问作者HenryMetarom
相关产品推荐
相关产品推荐

