2017-01-09 81 views
18

我與Laravel 5.3(在Windows服務器上)有同樣的問題。我做了所有可能的嘗試:檢查.env文件,配置,工匠新密鑰生成,緩存:清除,配置:清除,作曲家更新,但問題隨機存在。Random RuntimeException:唯一支持的密碼是AES-128-CBC和AES-256-CBC,密鑰長度正確

請注意,具有完全相同版本的apache,mysql,php的相同代碼在Mac OS上不會產生此問題。

我發現密鑰(加密器約束器的第一個參數)到達「有時」空,當然它失敗。大多數情況下,密鑰都是正確的,但隨機密鑰從EncryptionServiceProvider中清空,然後輪流將它請求到應用配置。

因此,唯一對我有用的解決方案是在EncryptionServiceProvider中添加一個if ($key),以便加密構造函數不會被空鍵調用。

當然不是一個「乾淨」的解決方案也不說明問題,但至少避免了尋找充滿錯誤日誌文件:

RuntimeException: The only supported ciphers are AES-128-CBC and AES-256-CBC and pages are displayed correctly.

如果這是一個錯誤Laravel我不知道,但當然,如果有人能解釋這一點,我會更樂意知道。

下面是我修改後的類:我只是說new Encrypterif ($key)行:

class EncryptionServiceProvider extends ServiceProvider 
{ 
    /** 
    * Register the service provider. 
    * 
    * @return void 
    */ 
    public function register() 
    { 
     $this->app->singleton('encrypter', function ($app) { 
      $config = $app->make('config')->get('app'); 

      // If the key starts with "base64:", we will need to decode the key before handing 
      // it off to the encrypter. Keys may be base-64 encoded for presentation and we 
      // want to make sure to convert them back to the raw bytes before encrypting. 
      if (Str::startsWith($key = $config['key'], 'base64:')) { 
       $key = base64_decode(substr($key, 7)); 
      } 
     if ($key) 
      return new Encrypter($key, $config['cipher']); 
     }); 
    } 
} 

更多細節和回溯日誌:

當然,我寫我檢查, .env文件,配置,工匠新密鑰生成,緩存:清除,配置:清除,作曲家更新。 這東西是可以的,因爲它工作99%的時間,但隨機我得到的錯誤。

這裏回溯追蹤:

[2017-01-09 10:25:40] test.ERROR: RuntimeException: The only supported ciphers are AES-128-CBC and AES-256-CBC with the correct key lengths. in C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Encryption\Encrypter.php:43

堆棧跟蹤:

#0 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Encryption\EncryptionServiceProvider.php(27): Illuminate\Encryption\Encrypter->__construct('', 'AES-256-CBC') 
#1 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Container\Container.php(746): Illuminate\Encryption\EncryptionServiceProvider->Illuminate\Encryption\{closure}(Object(Illuminate\Foundation\Application), Array) 
#2 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Container\Container.php(644): Illuminate\Container\Container->build(Object(Closure), Array) 
#3 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(709): Illuminate\Container\Container->make('encrypter', Array) 
#4 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Container\Container.php(864): Illuminate\Foundation\Application->make('encrypter') 
#5 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Container\Container.php(819): Illuminate\Container\Container->resolveClass(Object(ReflectionParameter)) 
#6 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Container\Container.php(788): Illuminate\Container\Container->getDependencies(Array, Array) 
#7 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Container\Container.php(644): Illuminate\Container\Container->build('App\\Http\\Middle...', Array) 
#8 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(709): Illuminate\Container\Container->make('App\\Http\\Middle...', Array) 
#9 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(127): Illuminate\Foundation\Application->make('App\\Http\\Middle...') 
#10 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) 
#11 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\View\Middleware\ShareErrorsFromSession.php(49): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request)) 
#12 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(137): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure)) 
#13 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) 
#14 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php(64): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request)) 
#15 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(137): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure)) 
#16 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) 
#17 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse.php(37): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request)) 
#18 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(137): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure)) 
#19 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) 
#20 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(104): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request)) 
#21 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Router.php(655): Illuminate\Pipeline\Pipeline->then(Object(Closure)) 
#22 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Router.php(629): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request)) 
#23 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Router.php(607): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request)) 
#24 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(268): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request)) 
#25 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(53): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request)) 
#26 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode.php(46): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request)) 
#27 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(137): Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure)) 
#28 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) 
#29 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(104): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request)) 
#30 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(150): Illuminate\Pipeline\Pipeline->then(Object(Closure)) 
#31 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(117): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request)) 
#32 C:\Apache24\htdocs\sph\public\index.php(53): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request)) 
#33 {main} 
+0

對此感興趣。有這個問題幾次,「簡單」重新安裝框架可以解決這個問題。我真的很想知道爲什麼。 – Loek

+0

你運行過'php工匠密鑰:生成'嗎? –

+0

另外,你有沒有嘗試'debug_print_backtrace();'當key *是* null?在每次調用時跟蹤調用堆棧和'error_log()'鍵值可能會很有趣。 –

回答

-3

它是如此簡單,APP_KEY.env文件複製到config/app.php -> key以下運行命令:

php artisan key:generate

-2

我安裝了Laravel 5.3,但沒有找到.env文件。而繁榮......這是問題。我在應用程序的根目錄下創建了.env文件並運行

php artisan key:generate

在終端中,它在終端中生成了base 64編碼的字符串。將該字符串複製到.env文件中作爲

APP_KEY=base64:************************************************

其中****是生成的編碼字符串。再次運行應用程序,它應該工作。

9

在多線程Web服務器而不是多進程Web服務器上使用線程安全版本的PHP時,會出現此問題。您可以在Github issue here,Github issue herePHP bug report here上稍微多讀一些問題。還有幾個鏈接,但他們只是從我發佈的那幾個中分出來的。

基本要點是,使用多線程Web服務器,您有一個處理多個線程的單個進程。但是,putenv()/getenv()方法不是線程安全的,並且在進程級別更改環境變量,因此該進程下的所有線程都會受到影響。

所以,你最終的東西是這樣的:(如this issue描述):

Request 1: {starts --- loads env --- work --- finishes} 
Request 2:        {starts ----- loads env --- work --- finishes} 

因此,請求1進來,加載環境優良,並開始工作。當請求1正在工作時,請求2進入並在另一個線程上啓動。在請求2讀取環境變量之前,請求1完成並且PHP清除由putenv()設置的所有變量。現在,請求2次嘗試讀取環境,但得到null,因爲當請求1完成時變量已被清除。

這個問題可以從兩個方面來緩解:

  1. 不要在生產中使用.env文件。直接設置環境變量,並禁用phpdotenv。這也被package itself建議:

    phpdotenv is made for development environments, and generally should not be used in production. In production, the actual environment variables should be set so that there is no overhead of loading the .env file on each request.

  2. 切勿使用env()方法配置文件之外,並確保您緩存您的配置文件。通過使用此方法,環境只讀一次:創建配置文件緩存時。每個實際的Web請求都會從緩存中讀取數據,並且環境變量將永遠不會再次被觸摸。

+0

@cytsunny只是想知道這個答案是你在找什麼。 – patricus

+0

我投了票。只是想等待看看有沒有更好的答案。 (例如使用.env解決問題,而不像OP那樣破解)如果在賞金結束之前沒有其他答案,將獎賞您的賞金。 – cytsunny

相關問題