Laravel5.5升级到5.5.42后遇到的Cookie序列化问题Somethingwentwrong!Sentry平台报错:openssl_encrypt()expectsparameter1tobestring,arraygiven。具体错误记录如下:ErrorExceptionopenssl_encrypt()expectsparameter1bestring,arraygivenvendor/laravel/framework/src/Illuminate/Encryption/Encrypter.phpinhandleErroratline91vendor/sentry/sentry/lib/Raven/Breadcrumbs/Openssl_encryptvendor/laravel/framework/src/Illuminate/Encryption/Encrypter.php在第34行的handleError中的ErrorHandler.phpIlluminate/Cookie/Middleware/EncryptCookies.php在encryptatline139vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.phpinhandle在line66vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php中Illuminate\Pipeline\{closure}在第149行vendor/laravel/framework/src/Illuminate/RoutingIlluminate\Routing\{closure}中的/Pipeline.php在第53行vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php然后在第102行vendor/laravel/framework/src/Illuminate/Routing/Router.php在runRouteWithinStack在660vendor/laravel/framework/src/Illuminate/Routing/Router.php在runRoute在635vendor/laravel/framework/src/Illuminate/Routing/Router.php在dispatchToRoute在601vendor/laravel/framework/src/Illuminate/Routing/Router.phpindispatchatline590vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.phpinIlluminate\Foundation\Http\{closure}atline176vendor/laravel/framework/src/Illuminate/Routing/Illuminate\Routing\{closure}中的Pipeline.php第30行vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php在句柄中第58行vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php在Illuminate\Pipeline\{closure}位于149vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php中Illuminate\Routing\{closure}atline53vendor/fideloper/proxy/src/TrustProxies.phpinhandleatline56vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.phpinIlluminate\Pipeline\{closure}atline149vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php在第53行的Illuminate\Routing\{closure}中vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php在第30行的句柄中/framework/src/Illuminate/Pipeline/Pipeline.phpinIlluminate\Pipeline\{closure}atline149vendor/laravel/framework/src/Illuminate/Routing/Pipeline.phpinIlluminate\Routing\{closure}atline53vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php在第30行的句柄中vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php在第149行的Illuminate\Pipeline\{closure}Illuminate\Routing\{closure}中的/src/Illuminate/Routing/Pipeline.php第53vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php在第27行的句柄中framework/src/Illuminate/Routing/Pipeline.php在第53行的Illuminate\Routing\{closure}中vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php在第46行的句柄中src/Illuminate/Pipeline/Pipeline.phpinIlluminate\Pipeline\{closure}atline149vendor/laravel/framework/src/Illuminate/Routing/Pipeline.phpinIlluminate\Routing\{closure}atline53vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php在102vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php在sendRequestThroughRouter在151vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel。phpinhandleatline116public/index.phpatline55仔仔细查看上面的异常堆栈记录,并进行断点调试,最终确定是由于Laravel5.5升级到小版本后Cookie加密的逻辑发生变化导致的错误。在查阅了Laravel官方文档(Laravel5.5升级指南)后了解到,新版本的Laravel不再能够利用PHP对象的序列化/反序列化漏洞。Cookie值会自动序列化和反序列化。例如:\Cookie::queue('user',['id'=>1,'name'=>'admin'],720,'/')Laravel更新到v5.5.42后,因为Laravel没有longer自动序列化cookie值['id'=>1,'name'=>'admin'],但是openssl_encrypt(string$data...)只能加密字符串数据,此时程序会抛出Error:openssl_encrypt()期望参数1为字符串,数组给定。解决方案:在新版本中,中间件AppHttpMiddlewareEncryptCookies增加了一个新的静态属性$serialize。当设置为true时,可以启用cookie值的自动序列化和反序列化。/***指示是否应序列化cookie。**@varbool*/protectedstatic$serialize=true;【推荐】使用JSON函数将Cookie值编码成字符串再存储(获取Cookie值函数后需要调用JSON进行解码)。\Cookie::queue('user',json_encode(['id'=>1,'name'=>'admin']),720,'/');-EOF-首发于知乎专栏《PHP和Laravel学习》:https://zhuanlan.zhihu.com/p/...扫描二维码关注《PHP和Laravel学习》微信公众号:
