Laravel接入现有Oracle用户表后认证跳转异常问题
问题分析与解决方案
你的核心问题出在User模型的主键配置,以及路由的语法错误,导致Laravel会话无法正确持久化用户身份,进而触发auth中间件的跳转逻辑。
1. 修复User模型的主键配置
你的用户表主键是字符串类型的LOGIN,但Laravel默认假设主键是自增整数。如果不明确声明主键类型和非自增属性,Laravel会把字符串主键强制转换为整数存储到会话中,导致后续验证时无法匹配到用户。
修改App\Models\User.php,添加以下两个属性:
<?php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { protected $table = "news.usuarios"; protected $primaryKey = 'LOGIN'; // 新增以下两行 public $incrementing = false; // 声明主键非自增 protected $keyType = 'string'; // 声明主键为字符串类型 public function getAuthPassword() { return $this->SENHA; } protected $fillable = [ 'LOGIN', 'SENHA', ]; protected $hidden = [ 'SENHA', ]; }
2. 修正路由的语法错误
你的路由代码最后多了一个多余的});,会导致路由分组解析异常,可能影响中间件的正常生效。修正后的路由如下:
Route::get('/login', [AuthController::class, 'showLoginForm'])->name('login'); Route::post('/login', [AuthController::class, 'login']); Route::group(['middleware' => ['auth:web'] ], function(){ Route::get('/landing-page', [LandingPage::class, 'index'])->name('landing-page'); }); // 移除多余的 });
3. 额外验证建议(可选)
虽然当前登录逻辑可以工作,但可以改用Laravel原生的Auth::attempt方法简化代码,同时保持和现有MD5密码的兼容:
// 在AuthController的login方法中替换查询逻辑 public function login(Request $request) { $request->validate([ 'LOGIN' => 'required', 'SENHA' => 'required', ]); // 直接传递原始密码,Laravel会自动调用getAuthPassword获取存储的MD5值进行比对 if (Auth::attempt(['LOGIN' => $request->LOGIN, 'SENHA' => $request->SENHA])) { Log::info('User logged in', ['user' => Auth::user()]); return redirect()->intended('landing-page'); } return back()->withErrors([ 'LOGIN' => 'The provided credentials do not match our records.', ]); }
注:因为你已经在User模型中定义了
getAuthPassword返回SENHA字段(存储的是MD5值),Auth::attempt会自动用输入的密码生成MD5后和数据库值比对,和你当前的逻辑一致。
原理说明
当你调用Auth::login($user)时,Laravel会把用户的主键值存储到会话中。如果主键是字符串但未声明$incrementing = false,Laravel会将其转换为整数(通常变成0),后续auth中间件验证时,会用这个错误的ID去查询用户,自然找不到,所以会跳回登录页。
内容的提问来源于stack exchange,提问作者Guilherme Hadba
相关产品推荐
相关产品推荐

