web-dev-qa-db-fra.com

Les demandes d'API avec axios toujours non autorisées avec Laravel API

Je travaille sur un projet personnel en utilisant la bibliothèque Laravel 5.6 et Axios (standard Laravel 5.6 package) .

Je dois d'abord envoyer GET puis POST requête en utilisant l'API de Laravel et les requêtes http d'Axios, mais je n'utilise pas Passport ou une bibliothèque comme celle-ci car c'est une API interne ne servant que VueJS pour obtenir des trucs à partir de la base de données.

Si je définis mes routes d'API à l'aide du middleware auth:api, J'obtiens toujours une réponse non autorisée, quel que soit le type de demande, voici la sortie d'erreur:

Erreur: la demande a échoué avec le code d'état 401

Le message :

message: "Unauthenticated."

Mais, comme je l'ai lu dans la documentation, les en-têtes axios sont définis dans bootstrap.js De laravel pour lire le jeton d'autorisation à partir des balises META (et le code est là):

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

Alors, si nécessaire, voici le code de demande http:

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

Alors, pourquoi ne suis-je pas authentifié si ceux-ci sont définis?

J'ai essayé de supprimer le middleware auth:api Et, bien sûr, cela fonctionne:

- Route::middleware('auth:api')->get('/latest', 'InternalApiController@latestEp');
+ Route::get('/latest', 'InternalApiController@latestEp');

Qu'est-ce que je fais mal?

6
K3nzie

Je n'utilise pas Passort ou une bibliothèque comme celle-ci, car il s'agit d'une API interne ne servant qu'à VueJS pour obtenir des éléments de la base de données.

Si l'API n'est pas sans état, ce qui signifie que l'utilisateur est connu pour être connecté avec un cookie de session standard, vous pouvez simplement utiliser la valeur par défaut 'web' middleware pour les routes API.

Dans la valeur par défaut RouteServiceProvider, modifiez la fonction mapApiRoutes pour utiliser le middleware web à la place:

protected function mapApiRoutes()
{
    Route::prefix('api')
        // ->middleware('api')
        ->middleware('web')
        ->namespace($this->namespace)
        ->group(base_path('routes/api.php'));
}

Cela étant dit, vous devriez vraiment mettre les routes d'API derrière la valeur par défaut 'auth' middleware car ils ne sont pas limités par défaut.

Dans le routes/api.php fichier:

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

Et si vous voulez vous assurer qu'il s'agit bien d'une demande AJAX, vous pouvez créer un middleware simple qui vérifie que la demande a le X-Requested-With en-tête défini sur 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);
    }
}

Et enregistrez-le dans le $routeMiddleware tableau à l'intérieur du \App\Http\Kernel classe.

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

Le jeton CSRF n'est pas identique à un jeton d'autorisation. Vous devrez probablement ajouter manuellement le jeton d'autorisation, qui est probablement comme this , selon votre méthode d'autorisation.

0
Lassi Uosukainen