I wanted to drop in an update of what I did. I created two user tables (users and admin).
Admin will be used for the admin portal and Users for everything else.
REST Routes
$_api = app('Dingo\Api\Routing\Router');
$_api->version('v1', function ($_api) {
$_api->get('/', function() {
return ['Hello' => 'World'];
});
// authenticate
$_api->post('admin/authenticate', 'App\Http\Controllers\AdminController@authenticate');
$_api->post('admin/user', 'App\Http\Controllers\AdminController@user');
});
REST Admin Controller will return a JWT Token if login is validated again the admin table
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use JWTAuth;
use Dingo\Api\Routing\Helpers;
use App\Transformers\AdminTransformer;
use App\Admin;
class AdminController extends Controller {
use Helpers;
/* check to see if the admin user exists */
public function authenticate(Request $_request) {
$_credentials = $_request->only('username', 'password');
try {
\Config::set('auth.providers.users.model', \App\Admin::class);
if (!$_token = JWTAuth::attempt($_credentials)) {
return $this->response->array(['error' => 'invalid credentials', 'status' => 401]);
}
} catch (JWTException $e) {
return $this->response->array(['error' => 'could not create your token', 'status' => 500]);
}
// all good so return the token and admin
if (!$_admin = JWTAuth::authenticate($_token)) {
return $this->response->array(['error' => 'user not found', 'status' => 404]);
}
return $this->response->array(['token' => compact('_token'), 'admin' => compact('_admin'), 'status' => 404]);
}
public function logout(Request $_request){
$this->validate($_request, [
'token' => 'required'
]);
\Config::set('auth.providers.users.model', \App\Admin::class);
JWTAuth::invalidate($_request->input('token'));
return $this->response->noContent();
}
public function user(){
try {
\Config::set('auth.providers.users.model', \App\Admin::class);
if (!$_admin = JWTAuth::parseToken()->authenticate()) {
return response()->json(['user_not_found'], 404);
}
} catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $_e) {
return response()->json(['token_expired'], $_e->getStatusCode());
} catch (\Tymon\JWTAuth\Exceptions\TokenInvalidException $_e) {
return response()->json(['token_invalid'], $_e->getStatusCode());
} catch (\Tymon\JWTAuth\Exceptions\JWTException $_e) {
return response()->json(['token_absent'], $_e->getStatusCode());
}
return response()->json(compact('_admin'));
}
public function getToken(){
\Config::set('auth.providers.users.model', \App\Admin::class);
$_token = JWTAuth::getToken();
if (!$_token) {
return $this->response->errorMethodNotAllowed('Token not provided');
}
try {
$_refreshed = JWTAuth::refresh($_token);
} catch (JWTException $_e) {
return $this->response->errorInternal('Not able to refresh Token');
}
return $this->response->withArray(['token' => $_refreshed]);
}
}
Client AdminController - which will trigger the REST call to try to login the admin user, I create a cookie of the JWT Token which we will check for on every request and if it's present then we can access all the routes with the middleware of token
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use Validator;
use App\Providers\RestServiceProvider;
use Illuminate\Support\Facades\Cookie;
class AdminController extends Controller {
private $_validator = array(
'rules' => array(
'username' => 'required|alpha|max:50|min:4',
'password' => 'required',
),
'messages' => array(
'required' => ':attribute is required.',
'alpha' => 'Only alpha values A-z are allowed.',
'max' => 'Only a :max characters are allowed.',
'min' => 'At lease :min characters must be entered.'
)
);
public function __construct(){
//$this->middleware('auth');
}
public function login(Request $_request){
$_validate = Validator::make($_request->all(), $this->_validator['rules'], $this->_validator['messages']);
if($_validate->fails()){
return response()->json(['errors' => $_validate->messages(), 'status' => 400], 200);
} else if($_request->ajax()) {
$_data = Input::all();
$_rest = new RestServiceProvider();
$_response = $_rest->request('POST', '/admin/authenticate', $_data);
if(!empty($_response)){
if(!empty($_response['error'])){
return response()->json(['errors' => $_response['error'], 'status' => 400], 200);
} else if(!empty($_response['token']) && !empty($_response['token']['_token'])) {
Cookie::queue(env('RESTAPI_TOKEN', 'resttoken'), $_response['token']['_token'], 60);
return response()->json(['success' => array('redirect'=> 'dashboard'), 'status' => 200], 200);
} else {
return response()->json(['success' => array('redirect'=> '404'), 'status' => 404], 404);
}
} else {
return response()->json(['errors' => array('fatal'=> 'sorry your request has been rejected.'), 'status' => 400], 200);
}
} else {
return response()->json(['errors' => array('fatal'=> 'sorry your request has been rejected.'), 'status' => 400], 200);
}
}
}
Client Routes
Route::get('/', function () {
return view('home');
});
Route::post('admin/login', 'AdminController@login');
Route::group(['middleware' => 'token'], function () {
Route::get('/dashboard', function () {
return view('dashboard');
});
});
AddHeaders - Middleware Token Class
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class AddHeaders
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
$_token = $request->cookie(env('RESTAPI_TOKEN', 'resttoken'));
if (!$_token) {
return redirect('/');
}
$request->headers->set('Authorization', "Bearer {$_token}");
return $next($request);
}
}
Let me know your thoughts?