Laravel多Auth Guard+Sanctum在部分虚拟主机验证失败问题
问题:Laravel多Auth Guard结合Sanctum在特定虚拟主机上认证失败
我基于Laravel框架开发了一个使用多Auth Guard结合Sanctum的项目,本地环境运行完全正常。但上传至某虚拟主机后,登录流程可正常执行并返回token,尝试获取用户详情时却提示未认证。将项目上传至其他虚拟主机则可正常运行,请问该问题可能的原因是什么?
config/auth.php
<?php return [ /* |-------------------------------------------------------------------------- | Authentication Defaults |-------------------------------------------------------------------------- | | This option controls the default authentication "guard" and password | reset options for your application. You may change these defaults | as required, but they're a perfect start for most applications. | */ 'defaults' => [ 'guard' => 'web', 'passwords' => 'users', ], /* |-------------------------------------------------------------------------- | Authentication Guards |-------------------------------------------------------------------------- | | Next, you may define every authentication guard for your application. | Of course, a great default configuration has been defined for you | here which uses session storage and the Eloquent user provider. | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | Supported: "session" | */ 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'memberGuard' => [ 'driver' => 'sanctum', 'provider' => 'memberP', ], 'adminGuard' => [ 'driver' => 'sanctum', 'provider' => 'adminP', ] ], /* |-------------------------------------------------------------------------- | User Providers |-------------------------------------------------------------------------- | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | If you have multiple user tables or models you may configure multiple | sources which represent each model / table. These sources may then | be assigned to any extra authentication guards you have defined. | | Supported: "database", "eloquent" | */ 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ], 'adminP' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ], 'memberP' => [ 'driver' => 'eloquent', 'model' => App\Models\Member::class, ], // 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ], ], /* |-------------------------------------------------------------------------- | Resetting Passwords |-------------------------------------------------------------------------- | | You may specify multiple password reset configurations if you have more | than one user table or model in the application and you want to have | separate password reset settings based on the specific user types. | | The expire time is the number of minutes that each reset token will be | considered valid. This security feature keeps tokens short-lived so | they have less time to be guessed. You may change this as needed. | */ 'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => 'password_resets', 'expire' => 60, 'throttle' => 60, ], 'adminGuard' => [ 'provider' => 'adminP', 'table' => 'password_resets', 'expire' => 60, 'throttle' => 60, ], 'memberGuard' => [ 'provider' => 'memberP', 'table' => 'password_resets', 'expire' => 60, 'throttle' => 60, ], ], /* |-------------------------------------------------------------------------- | Password Confirmation Timeout |-------------------------------------------------------------------------- | | Here you may define the amount of seconds before a password confirmation | times out and the user is prompted to re-enter their password via the | confirmation screen. By default, the timeout lasts for three hours. | */ 'password_timeout' => 10800, ];
Auth/MemberController.php
<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Models\Member; use App\Models\User; use App\Traits\ApiResponser; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Log; class MemberController extends Controller { use ApiResponser; /** * Create a new AuthController instance. * * @return void */ public function __construct() { $this->middleware('auth:memberGuard', ['except' => ['login']]); } /** * Authenticate user and create token. * * @return token */ public function login(Request $request) { Log::info('This is some useful information.'); $fields = $request->validate([ 'accppa_member_id' => 'required', 'password' => 'required|string', ]); // Check user name $user = Member::where('accppa_member_id', $fields['accppa_member_id'])->first(); // Check password if (!$user || !Hash::check($fields['password'], $user->password)) { return $this->error('Invalid Credentials', 401); } // Remove Existing tokens if ($user->tokens()->count() > 0) { $user->tokens()->delete(); } $token = $user->createToken(uniqid()); return $this->success([ 'token' => $token->plainTextToken ]); } /** * User * * @return void */ public function user() { $user = auth()->guard('memberGuard')->user(); return response()->json($user); } /** * Remove user token * * @return void */ public function logout(Request $request) { $request->user()->currentAccessToken()->delete(); return response()->json(['message' => 'Successfully logged out']); } }
可能的原因及排查方向
- PHP版本或扩展不兼容:确认该虚拟主机的PHP版本与本地一致,Laravel和Sanctum有明确的版本依赖;同时检查是否安装了
openssl、fileinfo等必需扩展,加密类扩展缺失会导致token验证失败。 - 环境变量配置错误:检查主机上的
.env文件,确保APP_KEY是有效的加密密钥(可通过php artisan key:generate重新生成),APP_URL与实际访问域名完全一致,SANCTUM_STATEFUL_DOMAINS包含当前主机域名。 - 缓存未清理:上传后未刷新配置缓存,旧的认证配置仍在生效。执行以下命令清理缓存:
php artisan config:clear php artisan cache:clear php artisan route:clear - 文件权限问题:Laravel的
storage和bootstrap/cache目录权限不足,导致Sanctum无法读写token数据。将这些目录权限设置为755,所有者改为Web服务器运行用户(如apache、www-data)。 - URL重写配置缺失:虚拟主机未正确配置Apache/Nginx的URL重写规则,导致请求无法到达Laravel入口文件,Sanctum无法解析
Authorization头。- Apache:确保
.htaccess文件存在且主机启用了mod_rewrite模块; - Nginx:配置文件中添加正确的try_files规则:
location / { try_files $uri $uri/ /index.php?$query_string; }
- Apache:确保
- 请求头被拦截:部分虚拟主机会拦截或修改
Authorization请求头,导致token无法被Sanctum接收。可临时通过URL参数?token=你的令牌测试请求,若能正常认证,说明是请求头问题,联系主机服务商解决。 - Sanctum配置问题:检查
config/sanctum.php中的stateful数组,确保包含当前主机的域名,尤其是使用子域名的场景。
内容的提问来源于stack exchange,提问作者Tharindu Prabodhana
相关产品推荐
相关产品推荐

