Els passos consisteixen en:
1) Afegir un camp a la taula users per guardar el token
// add this to your users_table migration $table->string('api_token', 60)->unique();
El camp pot ser simplement un str_random(60) però també podem utilitzar quelcom com:
md5(uniqid(rand(), true));
o
sha1(uniqid(rand(), true));
Vegeu API Key i Security Token
2) Laravel ha afegir el concepte de guard a l'autenticació (vegeu Autenticació i Laravel Autenticació). Un guard és el responsable de controlar l'accés a l'aplicació és a dir d'autenticar.
La configuració la podeu trobar a:
https://github.com/laravel/laravel/blob/master/config/auth.php
I podeu veure que Laravel porta de sèrie dos guards: web i api. El guard web és el de sempre el d'autenticació per Login i paraula de pas i gestionada a nivell de sessió. El guard api funciona amb token.
Resources:
3) Protegir rutes:
Route::group(['prefix' => 'api/v1', 'middleware' => 'auth:api'], function () { Route::post('/short', '[email protected]'); });
Un altre opció es protegir tot un controlador amb:
<?php namespace App\Http\Controllers; use App\Http\Requests; use Illuminate\Http\Request; /** * Class APIController * @package App\Http\Controllers */ class APIController extends Controller { /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('auth:api'); } /** * Show the application dashboard. * * @return Response */ public function index() { ... }
Auth és el normal que utilitzem com a midleware per protegir l'accés (guard web). Posant api protegim per API Token
4) Obtenir l'usuari per API:
Auth::guard('api')->user();
IMPORTANT: Si accediu a la API via navegador web veureu que us mostra una redirecció cap a la pàgina de Login. Això és normal per què el sistema d'API només s'utilitza quan la petició és per API vegem amb més detalls com funciona
Podeu utilitzar httpie:
$ http get URL_a_la_nostra_api
Però igual que per web us mostrarà una redirecció a la pàgina de login
En canvi amb:
$ http get URL_a_la_nostra_api --json
Us mostrarà l'esperat 401. Vegem el perquè al middlewate authenticate [1]:
public function handle($request, Closure $next, $guard = null) { if (Auth::guard($guard)->guest()) { if ($request->ajax() || $request->wantsJson()) { return response('Unauthorized.', 401); } else { return redirect()->guest('login'); } } return $next($request); }
La clau està en les funcions
$request->ajax() $request->wantsJson()
On:
public function ajax() { return $this->isXmlHttpRequest(); } public function isXmlHttpRequest() { return 'XMLHttpRequest' == $this->headers->get('X-Requested-With'); }
Així podeu fer un test de com utilitzant per exemple POSTMAN si poseu el header:
X-Requested-With = XMLHttpRequest
Laravel interpreta la petició com una petició per API.
Ara per comprovar que funciona correctament només falta indicar la variable api_token:
$ http URL_NOSTRA_API api_token=API_TOKEN_DUN_USUARI --json
O amb postman amb X-Requested-With = XMLHttpRequest crideu la URL:
URL_NOSTRA_API?api_token=API_TOKEN_DUN_USUARI
NOTA: El codi isXmlHttpRequest és de Symfony
Si observeu bé el codi de:
https://github.com/laravel/framework/blob/5.2/src/Illuminate/Auth/TokenGuard.php
També veureu que el token pot estar al header Authorization (Bearer Token) o simplement també amb el header PHP_AUTH_PW. Vegeu:
http://php.net/manual/es/features.http-auth.php
Recursos:
https://gistlog.co/JacobBennett/090369fbab0b31130b51
https://laracasts.com/series/whats-new-in-laravel-5-2/episodes/5