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?
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,
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.