Laravel7中Register与Login API运行异常但web端功能正常如何解决
问题原因
- 控制器方法访问权限与参数不匹配:默认
RegisterController中的create方法是protected受保护类型,无法被路由直接调用;且该方法仅支持数组类型参数,路由调用时框架会自动注入Request请求对象,参数类型不匹配直接抛出异常。 - 中间件冲突:Laravel默认生成的Auth控制器构造方法中默认绑定了
guest中间件,该中间件依赖session会话,而API请求为无状态,无会话数据,调用时会抛出异常。 - 逻辑缺失:
create方法仅负责用户数据创建,没有参数校验、响应格式化逻辑,也没有生成Passport的API访问令牌,不符合API接口的使用要求。 - 登录方法适配问题:
LoginController默认的login方法是为web端设计的,验证通过后会跳转页面,不会返回JSON格式的令牌数据,也不适合API场景使用。
修复方案
1. 适配注册接口逻辑
在RegisterController中新增公开的API注册方法,同时调整构造方法排除API路由的中间件校验:
<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; use App\User; use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; use Illuminate\Http\Request; // 引入Request类 class RegisterController extends Controller { use RegistersUsers; protected $redirectTo = RouteServiceProvider::HOME; public function __construct() { // 新增API方法排除guest中间件 $this->middleware('guest')->except(['logout', 'apiRegister']); } // 新增公开的API注册方法 public function apiRegister(Request $request) { // 参数校验 $validated = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:8|confirmed', 'phone' => 'required|string|unique:users', ]); // 调用原有create方法创建用户 $user = $this->create($validated); // 生成Passport访问令牌 $token = $user->createToken('API_TOKEN')->accessToken; // 返回JSON响应 return response()->json([ 'code' => 200, 'msg' => '注册成功', 'data' => [ 'user_info' => $user, 'access_token' => $token, 'token_type' => 'Bearer' ] ]); } protected function create(array $data) { return User::create([ 'first_name' => $data['name'], 'last_name' => $data['name'], 'email' => $data['email'], 'password' => bcrypt($data['password']), 'phone' => $data['phone'], 'user_type'=> "abc", ]); } }
2. 适配登录接口逻辑
在LoginController中新增公开的API登录方法,同时调整构造方法排除中间件校验:
<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; class LoginController extends Controller { use AuthenticatesUsers; protected $redirectTo = RouteServiceProvider::HOME; public function __construct() { // 新增API方法排除guest中间件 $this->middleware('guest')->except(['logout', 'apiLogin']); } // 新增公开的API登录方法 public function apiLogin(Request $request) { $credentials = $request->validate([ 'email' => 'required|email', 'password' => 'required' ]); if(!auth()->attempt($credentials)){ return response()->json([ 'code' => 401, 'msg' => '账号或密码错误' ],401); } $user = auth()->user(); $token = $user->createToken('API_TOKEN')->accessToken; return response()->json([ 'code' => 200, 'msg' => '登录成功', 'data' => [ 'user_info' => $user, 'access_token' => $token, 'token_type' => 'Bearer' ] ]); } }
3. 修改API路由
更新routes/api.php中的路由指向新增的API方法:
Route::group([ 'prefix' => 'auth' ], function () { Route::post('login', 'Auth\LoginController@apiLogin'); Route::post('register', 'Auth\RegisterController@apiRegister'); Route::group(['middleware' => 'auth:api'], function() { Route::get('logout', 'AuthController@logout'); Route::get('user', 'AuthController@user'); }); });
4. 检查Passport基础配置
确保以下配置正确:
config/auth.php中api guard驱动设置为passport:
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'passport', 'provider' => 'users', 'hash' => false, ], ],
- User模型已引入Passport的
HasApiTokenstrait:
use Laravel\Passport\HasApiTokens; class User extends Authenticatable { use HasApiTokens, Notifiable; // 其他原有逻辑 }
内容的提问来源于stack exchange,提问作者kapildevsharma
相关产品推荐
相关产品推荐

