使用 axios 的 API 请求总是未经 Laravel API 授权
Posted
技术标签:
【中文标题】使用 axios 的 API 请求总是未经 Laravel API 授权【英文标题】:API requests with axios always unauthorized with Laravel API 【发布时间】:2018-09-27 19:18:44 【问题描述】:我正在使用 Laravel 5.6 和 Axios 库(标准 Laravel 5.6 包)进行个人项目。
我需要使用 Laravel 的 API 和 axios 的 http 请求发送第一个 GET 然后 POST 请求,但我没有使用 Passport 或任何类似的库,因为它是一个仅服务于 VueJS 以从数据库获取内容的内部 API。
如果我使用 auth:api
中间件设置我的 API 路由,我总是会得到未经授权的响应,无论请求类型是什么,这是错误输出:
错误:请求失败,状态码为 401
消息:
message: "Unauthenticated."
但是,正如我在文档中所读到的,axios 标头设置在 laravel 的 bootstrap.js
中,以从元标记中读取授权令牌(代码就在那里):
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
// further down the file...
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token)
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
else
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
如果需要,这里是 http 请求代码:
axios.post('/api/latest', formData)
那么,如果设置了这些,为什么我会未经身份验证?
我已经尝试删除 auth:api
中间件,当然,它正在工作:
- Route::middleware('auth:api')->get('/latest', 'InternalApiController@latestEp');
+ Route::get('/latest', 'InternalApiController@latestEp');
我做错了什么?
【问题讨论】:
【参考方案1】:使用 Laravel 8,我在尝试从后端 api 请求某些内容时收到 401 错误。遵循接受的答案让我很接近,但它仍然没有用。我相信这是因为我在子域上的仪表板为users.mydomain.tld
,而我使用 Axios 的位置在主域上为mydomain.tld/some/path
。问题是会话 cookie 的路径。重新配置时,您需要清除所有 cookie(开发工具栏)。然后在您进行更改后像往常一样重新登录。否则,cookie 将被弄乱,您将无法看到它已修复,或者在您清除它们之前您将无法登录。
我恢复了我所做的所有更改(遵循公认的答案)并确定 SESSION_DOMAIN
环境变量是关键因素,至少当涉及到主要用户的区域位于子域时。
在您的.env
文件中:
SESSION_DOMAIN=".yourdomain.tld"
在app/Providers/RouteServiceProvider.php
中,在boot()
方法中将api
更改为web
:
Route::prefix('api')
//->middleware('api')
->middleware('web')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
在routes/api.php
:
Route::middleware('auth')->get('/user', function (Request $request)
return $request->user();
);
在你的resources/js/bootstrap.js
:
window.axios.defaults.withCredentials = true;
修改bootstrap.js
文件后,需要再次运行npm run dev
重新编译。
现在,您应该可以在前端 javascript 中使用 Axios。无论是 jQuery 还是 Vue,无论你在使用什么。
axios.get('/api/user')
.then(response => console.dir(response.data))
.catch(error => console.log(error));
【讨论】:
我更惊讶于我 3 年前的问题仍然受到关注哈哈,但很高兴知道!有用的信息【参考方案2】:我没有使用 Passort 或任何类似的库,因为它是一个内部 API,仅服务于 VueJS 以从数据库中获取内容。
如果 API 不是无状态的,这意味着已知用户使用标准会话 cookie 登录,那么您可以将默认的 'web'
中间件用于 API 路由。
在默认的RouteServiceProvider
中,将mapApiRoutes
函数改为使用web
中间件:
protected function mapApiRoutes()
Route::prefix('api')
// ->middleware('api')
->middleware('web')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
话虽如此,您确实应该将 API 路由放在默认的 'auth'
中间件后面,因为默认情况下它们不会受到限制。
在routes/api.php
文件中:
Route::group(['middleware' => 'auth'], function()
Route::get('/latest', 'InternalApiController@latest');
);
如果您想确保它是一个 AJAX 请求,您可以创建一个简单的中间件来检查该请求的 X-Requested-With
标头是否设置为 XMLHttpRequest
。
class RequestIsAjax
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
if (!$request->ajax())
return redirect()->route('login.index');
return $next($request);
并将其注册到 \App\Http\Kernel
类内的 $routeMiddleware
数组中。
protected $routeMiddleware = [
'ajax' => \App\Http\Middleware\RequestIsAjax::class,
【讨论】:
即使改变它,如果我把我的 api.phpRoute::middleware('auth:api')->get('/latest', 'InternalApiController@latest');
我仍然得到同样的错误
@K3nzie 您仍在使用 auth:api
来检查 api
身份验证保护。只需使用middleware('auth')
即可。
ok 修复了它,但是,这样 API 端点可以从 Web 访问,而只希望它在 Vue 中使用,这可能吗?
@K3nzie 我添加了一个简单的 AJAX 检查中间件,这将有助于隐藏 API 端点以防止浏览器意外导航。
像魅力一样工作!你救了我【参考方案3】:
CSRF-token 与授权令牌不同。您很可能需要手动添加授权令牌,这可能类似于 this,具体取决于您的授权方法。
【讨论】:
以上是关于使用 axios 的 API 请求总是未经 Laravel API 授权的主要内容,如果未能解决你的问题,请参考以下文章
在 Laravel 护照、vueJS 和 Axios 中获得未经授权的 401
对 MailChimp API v3 的发布请求总是返回未经授权的
在Laravel护照,vueJS和Axios中未经授权获得401
React Native axios 总是返回“请求失败,状态码 400”