使用Laravel API始终未经授权使用axios的API请求

时间:2018-04-17 17:57:43

标签: php laravel api axios

我正在使用Laravel 5.6和Axios库(标准Laravel 5.6包)开展个人项目。

我需要使用Laravel的API和axios的http请求发送第一个GET然后发送POST请求,但是我没有使用Passport或任何类似的库,因为它是一个内部API,只提供VueJS来从数据库中获取内容。

如果我使用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');

我做错了什么?

3 个答案:

答案 0 :(得分:9)

  

我没有使用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);
    }
}

并在$routeMiddleware类内的\App\Http\Kernel数组中注册。

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

答案 1 :(得分:2)

在 Laravel 8 中,当我尝试从后端 api 请求某些内容时收到 401 错误。按照接受的答案让我接近,但它仍然没有用。我相信这是因为我在子域上的仪表板为 users.mydomain.tld,而我使用 Axios 的位置在主域上为 mydomain.tld/some/path。问题是会话 cookie 的路径。重新配置时,您需要清除所有 cookie(开发工具栏)。然后在进行更改后像往常一样重新登录。否则,cookie 会被弄乱,您将看不到它已修复,或者您在清除它们之前根本无法登录。

我恢复了我所做的所有更改(遵循已接受的答案)并确定 SESSION_DOMAIN 环境变量是关键因素,至少在主要用户区域位于子域中时是这样。< /p>

在您的 .env 文件中:

SESSION_DOMAIN=".yourdomain.tld"

app/Providers/RouteServiceProvider.php 中,在 api 方法中将 web 更改为 boot()

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

答案 2 :(得分:0)

CSRF-token与授权令牌不同。您很可能需要手动添加授权令牌,这可能与this相似,具体取决于您的授权方式。