環境
php8.2
Laravel11
heroku-22
JawsDB mysql
Buildpacks
heroku/php
heroku/node.js
アプリの仕様:
生成AIを使用してブログ記事を自動生成させるもの。 /にアクセスするとログイン画面が表示され ログインに成功すると生成可能残数が表示される。 ログインはsessionで管理。導入背景:
ローカルではDockerで開発したのでherokuもDockerで動かそうと思ったのですが デプロイ後に403Forbiddenから抜け出せなくなったので やむなくstackをheroku-22を使うことに。起きた問題:
ローカルではトップ画面にログイン画面が出力されて、userとpassを入力すればログインできていました。 しかしherokuにデプロイした後はIDとPASSを入力しても再びログイン画面が表示されてしまうことに。herokuのログをみると以下のことがわかりました。
[2024-07-06 21:18:32 Asia/Tokyo] [2024-07-06 21:18:32] production.INFO: Login attempt: {"name":"generateArticle","password":"********:"}
[2024-07-06 21:18:33 Asia/Tokyo] [2024-07-06 21:18:33] production.INFO: Login failed. User not found or password incorrect.
ログインIDとpassが間違っていると。
つまりsession()にログイン情報が保存されていない可能性がある。
localではできてherokuで出来ないのは気持ち悪いのが正直な意見。
現況:
LoginController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
public function login(Request $request)
{
$credentials = $request->only('name', 'password');
\Log::info('Login attempt:', $credentials);
$user = \App\Models\User::where('name', $credentials['name'])->first();
if ($user) {
\Log::info('User found:', ['id' => $user->id, 'name' => $user->name]);
} else {
\Log::info('User not found');
}
if (Auth::attempt($credentials)) {
\Log::info('Authentication successful');
$request->session()->regenerate();
return redirect()->intended('/');
}
\Log::info('Authentication failed');
return back()->withErrors([
'name' => 'The provided credentials do not match our records.',
])->withInput($request->only('name'));
}
bootstrap/app.php
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken; //追加 CSRF保護
use Illuminate\View\Middleware\ShareErrorsFromSession; //追加 sessionエラーの共有
use App\Http\Middleware\CheckUsageLimit;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [ //追加 ミドルウェア追加
VerifyCsrfToken::class, //追加 CSRF保護追加
ShareErrorsFromSession::class, //追加 sessionエラー追加
]);
$middleware->alias([
'check.usage.limit' => CheckUsageLimit::class,
]);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
laravel11のミドルウェア設定はbootstrap/app.phpで行うのでこのファイルを編集。
LoginController.phpで記述したauthがミドルウェアに記述されておらず。
そこで下記のコードを追加
LoginController.php
use Illuminate\Auth\Middleware\Authenticate; // 追加 承認処理 これがなかったのでauth承認できなかった(herokuでの話し
$middleware->alias([
'auth' => Authenticate::class, //追加 ここでミドルウェアを使えるようにしてる
'check.usage.limit' => CheckUsageLimit::class,
]);
※middlewareのauthenticateミドルウェアをauthというエイリアス(要はショートカット)で使用可能にし、承認情報を検証してる
念の為パスワードも同じ文字列で更新。
以上を実装したらログインができるようになりました。
解決できてないこと:
なぜlocalで動いたものがherokuだと動かないのだろうか...。