Laravel 5.6 API搭配Axios请求始终返回未授权问题求助
嘿,我之前也踩过这个坑!Laravel 5.6的auth:api中间件默认是基于token驱动的,而你没配置对应的token认证机制(比如Passport或者手动API token),所以不管发GET还是POST请求,服务器都认不出你的身份,自然返回未授权。
结合你的场景(内部API给VueJS用,不想折腾Passport),给你两个最实用的解决方案:
方案一:手动实现API Token认证(继续用auth:api)
这个方案适合你想保持API无状态的情况:
给用户表添加api_token字段
先生成迁移文件:php artisan make:migration add_api_token_to_users_table --table=users打开迁移文件,添加字段定义:
public function up() { Schema::table('users', function (Blueprint $table) { $table->string('api_token', 80)->unique()->nullable()->default(null); }); }执行迁移:
php artisan migrate为用户生成API Token
可以在用户登录或注册时自动生成token,比如在登录控制器的login方法里:if (Auth::attempt($credentials)) { $user = Auth::user(); if (!$user->api_token) { $user->api_token = Str::random(60); $user->save(); } return response()->json(['token' => $user->api_token]); }Axios请求时携带Token
登录后把token存在localStorage或Vuex里,然后全局配置Axios或者单个请求携带:// 全局配置,所有请求自动带token axios.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('api_token'); // 单个请求单独设置 axios.post('/api/save-data', yourData, { headers: { 'Authorization': 'Bearer ' + localStorage.getItem('api_token') } });
方案二:改用Session认证(更适合同域内部API)
如果你的Vue和Laravel是同域部署(比如Vue放在Laravel的public目录下),用Session认证更省心,不用折腾token:
修改API路由的中间件
直接把API路由的中间件从auth:api改成auth:web:Route::middleware('auth:web')->group(function () { Route::get('/api/get-data', 'YourController@getData'); Route::post('/api/save-data', 'YourController@saveData'); });让API路由支持Session
默认Laravel的api中间件组没有加载Session相关中间件,需要手动添加。打开app/Http/Kernel.php,修改api中间件组:'api' => [ 'throttle:60,1', 'bindings', \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, ],Axios自动携带Cookie
同域下Axios默认会自动发送Cookie,你登录Laravel后Session会保持,API请求就能直接通过认证了。如果是跨域场景,还需要给Axios设置withCredentials: true,同时在Laravel里配置CORS(不过你是内部API,大概率不用)。
额外小技巧
如果你想继续用auth:api中间件但改用Session认证,可以修改config/auth.php里的api guard驱动:
'guards' => [ 'api' => [ 'driver' => 'session', // 把默认的token改成session 'provider' => 'users', ], ],
这样就不用改路由,直接用auth:api就能实现Session认证了。
内容的提问来源于stack exchange,提问作者K3nzie

