J'ai implémenté avec succès JWT dans Laravel et tout fonctionne bien. Connexion, déconnexion.

Mais chaque fois que je veux ajouter une nouvelle route dans mon routes/api.php et essayer de l'utiliser avec un contrôleur, j'obtiens un 401 Unauthenticated. Il semble que le contrôleur n'est pas adressé car aucun var_dump ne revient.

Mon config/auth.php

'guards' => [
   'web' => [
       'driver' => 'session',
       'provider' => 'users',
   ],

   'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

Ma demande:

let myConfig = {
    headers: {
        Authorization: "Bearer " + 'JWT_SECRET'
    }
}

axios.get('http://localhost/api/getcashboxes', myConfig)
.then(res => {
    console.log(res.data)
}).catch(err => {
    console.log(err)
})

Mon routes/api.php

use Illuminate\Http\Request;

Route::get('getcashboxes', 'CashboxController@getcashboxes')->name('getcashboxes');

Route::group(['prefix' => 'auth'], function ($router) {

    Route::post('login', 'AuthController@login');
    Route::post('logout', 'AuthController@logout');
    Route::post('refresh', 'AuthController@refresh');
    Route::post('me', 'AuthController@me');

});

Mon CashboxController.php

namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class CashboxController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login']]);
        //$this->middleware('auth:api'); //Does not work too
    }

    public function getcashboxes()
    {
        var_dump("Hello World :)");
    }
}

En-tête de demande:

Accept
    application/json, text/plain, 
Accept-Encoding
    gzip, deflate
Accept-Language
    de,en-US;q=0.7,en;q=0.3
Authorization
    Bearer 5zqyH1BrQUbiDRefurc5XaduzaTyCXPlcPXbodDHhsgdjJHU1dDHhsgdjefur
Cache-Control
    max-age=0
Connection
    keep-alive
Cookie
    XSRF-TOKEN=eyJpdiI6IlVjRFwvYkRvaSs3cDBCVFkxMFZtZkhRPT0iLCJ2YWx1ZSI6Imw4WlZ3RlwvVjNQemZOaTRQXC84MDlrd01uc0dFeUZ4eCtuR29jcWFqTGZBY3RkdzdFdFpzWjB4UDZOQzhQYXRTUCIsIm1hYyI6ImE5ODFkODM1ODU3M2Q3ZDEyZDY1NjdiYTY3ZGJkN2FlNGIzYWRiZTcxNjI4ODc3MmZkYzg3MGZjMzhmODlhODkifQ%3D%3D; buywatchvue_session=eyJpdiI6IjFSb25ZdmthalF2Tm1TWjM4cnUzRkE9PSIsInZhbHVlIjoiQms0SDNGNlFPcXM1YVR2MTZzeEJpRkc1MnlPeFlGOW5IRlRVR0pTZWI3MUk2XC9RMUdsYVp5SWQyTnJRcitoazIiLCJtYWMiOiI0ZmYyNjQxOWY0NjAxNzM4NzY2YzBmYjY2Mjc2OTcyNTE0ZjVkYzdlMDU2YzE0MWE4Y2U2MzZmNTFkNzU2MWY4In0%3D; laravel_session=eyJpdiI6Ik4wNGRJM3Q5QU5KRUlIbWZoaUE4VkE9PSIsInZhbHVlIjoiNmNLb09JeU5DRksxM1VNMElPNDNQb1NseVNJYWdTdXpZdnZyS1RuMlVRY043OUJcLzREMXhkaWR3TmR6ZklWaWIiLCJtYWMiOiJmYWViNzIxMmZjYTU1N2UwYmI2OTU3YzAyNmFmNzM3NjAyMzY5N2Q2MTAyMzEwNzc1MDZlZWQzMjE4YWZiN2UyIn0%3D
Host
    localhost
Referer
    http://localhost
User-Agent
    Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0
X-CSRF-TOKEN
    DClSR93LzbeM4SZQ9OzZJ89s5jtiNFOfkWabYMSJ
X-Requested-With
    XMLHttpRequest
X-XSRF-TOKEN
    eyJpdiI6IlVjRFwvYkRvaSs3cDBCVFkxMFZtZkhRPT0iLCJ2YWx1ZSI6Imw4WlZ3RlwvVjNQemZOaTRQXC84MDlrd01uc0dFeUZ4eCtuR29jcWFqTGZBY3RkdzdFdFpzWjB4UDZOQzhQYXRTUCIsIm1hYyI6ImE5ODFkODM1ODU3M2Q3ZDEyZDY1NjdiYTY3ZGJkN2FlNGIzYWRiZTcxNjI4ODc3MmZkYzg3MGZjMzhmODlhODkifQ==

En-tête de réponse:

Cache-Control
    no-cache, private
Connection
    Keep-Alive
Content-Length
    30
Content-Type
    application/json
Date
    Sat, 22 Aug 2020 14:12:25 GMT
Keep-Alive
    timeout=5, max=99
Server
    Apache/2.4.37 (Win32) OpenSSL/1.1.1a PHP/7.3.0
Vary
    Authorization
X-Powered-By
    PHP/7.3.0

Quelqu'un a une idée?

0
Tenarius 22 août 2020 à 17:15

2 réponses

Meilleure réponse

J'ai trouvé la solution. C'était un manque de connaissances sur le fonctionnement des jetons Web JSON (JWT).

Le principe expliqué simplement: Si l'utilisateur est connecté depuis le serveur, il récupère un JWT. Ce JWT doit maintenant être enregistré côté client sous forme de cookie ou dans le stockage local. Ceci est nécessaire pour les demandes ultérieures du serveur.

Si une demande nécessitant une autorisation est envoyée au serveur, le JWT doit être envoyé dans l'en-tête.

Il doit donc être lu à partir du cookie ou du stockage local. Avec Laravel, Vue, Vuex, Axios et le local storage, cela peut ressembler à ceci:

Récupérer le jeton du serveur (AuthController.php):

public function login()
{
    $credentials = request(['email', 'password']);

    if (! $token = auth('api')->attempt($credentials)) {
        return response()->json(['error' => 'Unauthorized'], 401);
    }

    return $this->respondWithToken($token);
}

Mutation de connexion dans vuex (store.js):

mutations: {
    loginSuccess(state, payload) {
        state.auth_error = null;
        state.isLoggedIn = true;
        state.loading = false;
        state.currentUser = Object.assign({}, payload.user, {token: payload.access_token});
    
        localStorage.setItem("user", JSON.stringify(state.currentUser));
    },
},

Obtenez l'utilisateur local, y compris le jeton JWT:

function getLocalUser() {
    const userStr = localStorage.getItem("user");

    if(!userStr) {
        return null;
    }

    return JSON.parse(userStr);
}

Créez une requête axios à l'aide du jeton JWT du magasin local:

const instance = axios.create({
    baseURL: 'http://localhost/api'
});

instance.defaults.headers.common['Authorization'] = `Bearer ${getLocalUser().token}`;

instance.get('/test')
.then(res => {
    console.log(res.data)
}).catch(err => {
    console.log(err)
})

J'espère que je peux aider quelqu'un avec ça. Sinon, vous trouverez plus d'informations sur JWT ici. Merci à Jonathan Akwetey Okine pour l'inspiration.

0
Tenarius 23 août 2020 à 11:04

Vous pouvez créer une instance d'axios et l'utiliser comme je l'ai fait.

const instance = axios.create({
baseURL: 'http://localhost/api'
});

instance.defaults.headers.common['Authorization'] = `Bearer ${token}`;

instance.get('/getcashboxes')
.then(res => {
console.log(res.data)
}).catch(err => {
console.log(err)
 })

Veuillez me faire savoir si cela vous aide à résoudre le problème.

1
Jonathan Akwetey Okine 22 août 2020 à 19:22