带有 axios 的 API 请求总是未经 Laravel API 授权 [英] API requests with axios always unauthorized with Laravel API
问题描述
我正在使用 Laravel 5.6 和 Axios 库(标准 Laravel 5.6 包).
I'm working on a personal project using Laravel 5.6 and Axios library (standard Laravel 5.6 package).
我需要先使用 Laravel 的 API 和 axios 的 http 请求发送 GET 然后 POST 请求,但我没有使用 Passport 或任何类似的库,因为它是一个内部 API,仅提供 VueJS 以从数据库中获取内容.
I need to send first GET then POST request using Laravel's API and axios' http requests, but I'm not using Passport or any library like that since it's an internal API serving only VueJS to obtain stuff from the database.
如果我使用 auth:api
中间件设置我的 API 路由,我总是得到未经授权的响应,无论请求类型是什么,这是错误输出:
If I set my API routes using auth:api
middleware, I always get unauthorized response, whichever is the request type, this is the error output :
错误:请求失败,状态码为 401
Error: Request failed with status code 401
消息:
message: "Unauthenticated."
但是,正如我在文档中读到的那样,axios 标头设置在 laravel 的 bootstrap.js
中以从元标记读取授权令牌(代码就在那里):
But, as I read in the documentation, axios headers are set inside laravel's bootstrap.js
to read the authorization token from meta tags (and the code is there) :
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 请求代码:
While, if needed, here's the http request code :
axios.post('/api/latest', formData)
那么,如果设置了这些,为什么我没有经过身份验证?
So, why am I unauthenticated if those are set?
我已经尝试删除 auth:api
中间件,当然,它是有效的:
I've tried removing the auth:api
middleware and, of course, it's working:
- Route::middleware('auth:api')->get('/latest', 'InternalApiController@latestEp');
+ Route::get('/latest', 'InternalApiController@latestEp');
我做错了什么?
推荐答案
我没有使用 Passort 或任何类似的库,因为它是一个内部 API,只为 VueJS 提供服务以从数据库中获取内容.
I'm not using Passort or any library like that since it's an internal API serving only VueJS to obtain stuff from the database.
如果 API 不是无状态的,这意味着已知用户使用标准会话 cookie 登录,那么您可以只使用默认的 'web'
中间件作为 API 路由.
If the API is not stateless, meaning that the user is known to be logged in with a standard session cookie, then you can just use the default 'web'
middleware for the API routes.
在默认的 RouteServiceProvider
中,将 mapApiRoutes
函数更改为使用 web
中间件:
In the default RouteServiceProvider
, change the mapApiRoutes
function to use the web
middleware instead:
protected function mapApiRoutes()
{
Route::prefix('api')
// ->middleware('api')
->middleware('web')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
<小时>
话虽如此,您确实应该将 API 路由放在默认的 'auth'
中间件之后,因为它们默认不受限制.
That being said, you should really put the API routes behind the default 'auth'
middleware since they're not throttled by default.
在 routes/api.php
文件中:
Route::group(['middleware' => 'auth'], function() {
Route::get('/latest', 'InternalApiController@latest');
});
如果你想确保它是一个 AJAX 请求,你可以创建一个简单的中间件来检查请求是否将 X-Requested-With
标头设置为 XMLHttpRequest
.
And if you want to ensure it's an AJAX request, you can create a simple middleware that checks that the request has the X-Requested-With
header set to 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
数组中注册它.
And register it within the $routeMiddleware
array inside the \App\Http\Kernel
class.
protected $routeMiddleware = [
'ajax' => \App\Http\Middleware\RequestIsAjax::class,
这篇关于带有 axios 的 API 请求总是未经 Laravel API 授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!