带有Larios API的未经授权的axios API请求 [英] API requests with axios always unauthorized with Laravel API

查看:150
本文介绍了带有Larios API的未经授权的axios API请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Laravel 5.6和 5.6 程序包).

我需要先使用Laravel的API和axios的http请求发送GET请求,然后发送POST请求,但是我没有使用Passport或类似的库,因为它是仅服务VueJS从数据库中获取内容的内部API.

如果我使用auth:api中间件设置我的API路由,我总是会得到未经授权的响应,无论是哪种请求类型,这都是错误输出:

错误:请求失败,状态码为401

消息:

message: "Unauthenticated."

但是,正如我在文档中所读到的那样,在laravel的bootstrap.js中设置了axios标头,以从元标记中读取授权令牌(并且代码在那里):

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');

我在做什么错了?

解决方案

我没有使用Passort或任何类似的库,因为它是仅服务VueJS从数据库中获取内容的内部API.

如果API不是无状态的,则意味着已知用户已使用标准会话cookie登录,那么您可以对API路由使用默认的'web'中间件.

在默认的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,

I'm working on a personal project using Laravel 5.6 and Axios library (standard Laravel 5.6 package).

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.

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 :

Error: Request failed with status code 401

The message :

message: "Unauthenticated."

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');
}

While, if needed, here's the http request code :

axios.post('/api/latest', formData)

So, why am I unauthenticated if those are set?

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');

What am I doing wrong?

解决方案

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.

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.

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'));
}


That being said, you should really put the API routes behind the default 'auth' middleware since they're not throttled by default.

In the routes/api.php file:

Route::group(['middleware' => 'auth'], function() {
    Route::get('/latest', 'InternalApiController@latest');
});

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);
    }
}

And register it within the $routeMiddleware array inside the \App\Http\Kernel class.

protected $routeMiddleware = [
    'ajax' => \App\Http\Middleware\RequestIsAjax::class,

这篇关于带有Larios API的未经授权的axios API请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆