419 CSRF token 过期 !

问题

项目在运行一段时间后 csrf token 会过期,然后419错误,根据异常找到抛出错误的地方,查看其实是有csrf token的,开始的时候以为是不小心做了啥操作,就没在意,php artisan key:generate 重置key后就没事了,后面部署到服务器上后就没有了,过了几天又有了,奇怪的是 在谷歌浏览器上会有问题,在苹果的浏览器上就没事了,同时 谷歌浏览器的话过一段时间又好了,而且不知道怎么复现,我初步才测试因为session过期时间之类的导致的,但是不知道该怎么做,请大家给个解决方案,或者是说排查方向!

基础环境

  • PHP >= 7.1.3
  • laravel = 5.8.18

服务器环境

homestead

扩展

  • encore/laravel-admin ^1.6
  • endroid/qr-code ^3.6
  • fideloper/proxy ^4.0
  • intervention/image ^2.4
  • jacobcyl/ali-oss-storage ^1.1
  • laravel/framework 5.8.*
  • laravel/tinker ^1.0
  • laravolt/avatar ^2.2
  • maatwebsite/excel ^3.1
  • mews/captcha ^2.2
  • overtrue/easy-sms ^1.1
  • overtrue/laravel-lang ~3.0
  • overtrue/laravel-pinyin ~3.0
  • overtrue/laravel-socialite ~2.0
  • predis/predis ^1.1
  • yansongda/pay ^2.7

kingofzihua

朕略显ぼうっと萌
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
朕略显ぼうっと萌
最佳答案

经过修改项目运行一周了,未再次出现,在这里整理下解决的方法:

  • 保证env中APP_NAME不是中文并且不重复
  • 在env中设置 唯一不重复的 SESSION_COOKIE
  • 设置 SESSION_DOMAIN
  • 如果SESSION_DRIVER=file 时 注意 storage 权限
  • 使用 https

SESSION_COOKIE、SESSION_DOMAIN 设置

其实根本问题就是 SESSION_COOKIE重复了,如果 SESSION_COOKIE 如果不配置的话 默认是自动生成的

'cookie' => env(
        'SESSION_COOKIE',
        Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
 ),

如果本地开发环境和 测试服务器或者线上服务器 APP_NAME相同 的话 必须要设置 SESSION_DOMAIN,不然会形成session 冲突。

APP_NAME中文 :

Str::slug(env('APP_NAME', 'laravel') 获取session前缀的时候会忽略中文名,也可能不小心导致 APP_NAME相同

最后附上参考链接:github讨论的链接

3个月前 评论
讨论数量: 7

是有过期时间的,如果你所说的页面对这个csrf_token没有很强的需求,可以通过在中间件里面指定对应的路由排除掉

// app/Http/Middlewares/VerifyCsrfToken.php
class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        // 这里可以指定需要排除的路由
        'wechat/*', // 例如排除以wechat开头的任意路由
    ];
}
3个月前 评论
朕略显ぼうっと萌

@FMW 这个不能排除的,csrf token 失效的话,整个的网站的form表单都会不能提交。这个肯定是不行的!

3个月前 评论
Epona

https://twitter.com/barryvdh/status/113366...

推上也有人出现这个问题,可能的原因据说是和自动提交有关? 总的来说不是代码的问题。

3个月前 评论

@朕略显ぼうっと萌 我没说排除所有啊 :joy:,就排除特定的那个路由啊,如果不排除,那就想办法提高过期时间吧,因为这准确来说是使用者的问题,并不是程序本身的问题,因为时间久过期了,这个行为是符合程序设计的预期的,并不是问题,而你这里的问题是你的需求所导致的。

3个月前 评论
朕略显ぼうっと萌

@FMW 这个并不是需求的问题,就正常登陆的话,就会出现csrf过期

3个月前 评论
朕略显ぼうっと萌

@Epona 谢谢老板,这个资料很重要,里面有github讨论的链接

3个月前 评论
朕略显ぼうっと萌

经过修改项目运行一周了,未再次出现,在这里整理下解决的方法:

  • 保证env中APP_NAME不是中文并且不重复
  • 在env中设置 唯一不重复的 SESSION_COOKIE
  • 设置 SESSION_DOMAIN
  • 如果SESSION_DRIVER=file 时 注意 storage 权限
  • 使用 https

SESSION_COOKIE、SESSION_DOMAIN 设置

其实根本问题就是 SESSION_COOKIE重复了,如果 SESSION_COOKIE 如果不配置的话 默认是自动生成的

'cookie' => env(
        'SESSION_COOKIE',
        Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
 ),

如果本地开发环境和 测试服务器或者线上服务器 APP_NAME相同 的话 必须要设置 SESSION_DOMAIN,不然会形成session 冲突。

APP_NAME中文 :

Str::slug(env('APP_NAME', 'laravel') 获取session前缀的时候会忽略中文名,也可能不小心导致 APP_NAME相同

最后附上参考链接:github讨论的链接

3个月前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!