'How to use access_token to authenticate SPA with Laravel 5.4
I'm trying to authenticate my single page app (written in Marionette) with my Laravel 5.4 app. In my previous experience, an SPA would:
send the username & password to an
/api/login-token
endpoint which would return with something like the following:{ "access_token":"-wt7x8UPRH9GcbTeUQ3wIA7zuc02XeHil4qsoKJcOUU", "type":"Bearer", "expires_in":2570, "refresh_token":"g9zmNkC1zpQ8fM0uSeJdy_VZe7TuBUG4MYGIBuAtXvg" }
the SPA will store the
access_token
in the browser's localstorage, and send it in anaccess_token
header with every subsequent request made to the backend- the backend will recognise this
access_token
and authenticate the user
Unfortunately I'm struggling to understand how to achieve this in Laravel 5.4.
Do I need to use Passport? I really don't think I need OAuth2, but does Passport also offer simple token-based auth? It seems to, and I have gotten the expected tokens described above from the /oauth/token
endpoint, but I don't know how to use this token. I don't think it's even for this purpose.
I tried sending a request to /api/user
with this token in the headers, POSTing it, and as a query string, with no luck. Also making me concerned is the expires_in
from Laravel is a year (31536000 seconds = 365 days) which seems way too long. I'm worried this Passport OAuth token is actually for OAuth2 access and not a 1-day-ish expiring access token that I'm used to.
I also read about Laravel's TokenGuard
but that seems like some weird kind of token that's stored in an api_token
column on the user
table, which is all wrong by my mindset. For example, it doesn't expire, and it's per-user not per-user-session, meaning the same token would have to be used from multiple devices. etc
Very confused... grateful for any help!
Solution 1:[1]
I actually ended up using Passport, based on some really helpful code found at https://laracasts.com/discuss/channels/code-review/api-authentication-with-passport?page=1&replyId=282168:
routes/api.php
Route::post('auth/token', 'Api\Auth\DefaultController@authenticate');
Route::post('auth/refresh', 'Api\Auth\DefaultController@refreshToken');
app/Http/Controllers/Api/Auth/DefaultController.php
<?php
namespace App\Http\Controllers\Api\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Route;
class DefaultController extends Controller
{
/**
* @var object
*/
private $client;
/**
* DefaultController constructor.
*/
public function __construct()
{
$this->client = DB::table('oauth_clients')->where('id', 2)->first();
}
/**
* @param Request $request
* @return mixed
*/
protected function authenticate(Request $request)
{
$request->request->add([
'username' => $request->username,
'password' => $request->password,
'grant_type' => 'password',
'client_id' => $this->client->id,
'client_secret' => $this->client->secret,
'scope' => '*'
]);
$proxy = Request::create(
'oauth/token',
'POST'
);
return Route::dispatch($proxy);
}
/**
* @param Request $request
* @return mixed
*/
protected function refreshToken(Request $request)
{
$request->request->add([
'grant_type' => 'refresh_token',
'refresh_token' => $request->refresh_token,
'client_id' => $this->client->id,
'client_secret' => $this->client->secret,
]);
$proxy = Request::create(
'/oauth/token',
'POST'
);
return Route::dispatch($proxy);
}
}
Solution 2:[2]
You may try JWT and this tutorial might be an inspiration for you: https://scotch.io/tutorials/token-based-authentication-for-angularjs-and-laravel-apps
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Oluwatobi Samuel Omisakin |