2
votes

I have created Web App that use angular 4 frontend and Larvel Backend for create Rest Api.

It use middleware that protect APi using token. When user login from frontend Angular, 'token' generates in backend(laravel) which store in session and send in response. That token is send through each request after login in headers 'Authorization'.

custom controller: LoginController

use Session;
class LoginController extends Controller
{
    public function authenticate(Request $request)
    {
        //....validate user login data.....

        $token = md5(uniqid(rand(), true));
        Session::put('token', $token);
        // ....send token in response...
    }
}

Middleware: RoleMiddleware

use Session;
class RoleMiddleware
{
   public function handle($request, Closure $next)
   {
      $token = Session::get('token');
      //why token appears empty here
       $header = $request->header('Authorization');
     if($header == $token){
       return $next($request);
     }

   }

}

Api Route :

Route::post('login', 'Settings\LoginController@authenticate');
Route::get('users/get/{email}', 'UserController@profile')->middleware('token');

kernel.php :

class Kernel extends HttpKernel
{

  protected $middleware = [
          /////.........
               ......
               .....
          \Illuminate\Session\Middleware\StartSession::class,
   ];


protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Session\Middleware\StartSession::class,
        'throttle:60,1',
        'bindings',
    ],
];

/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
    'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'token' => \App\Http\Middleware\RoleMiddleware::class,
];
}
1

1 Answers

3
votes

First: API authentication is stateless, meaning that session/cookies are not used to authenticate the user in your system.

Second: Laravel session its booted on web routes only, however you can switch it to boot in api routes, but I do not think its the right choice here . However if you want to make it work make sure you boot those middlewares on api group before booting your RoleMiddleware.

'api' => [
    \App\Http\Middleware\EncryptCookies::class,
    \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
    \Illuminate\Session\Middleware\StartSession::class,
    \App\Http\Middleware\RoleMiddleware::class
    'throttle:60,1',
    'bindings',
];

Third: Use [JWT Authentication][1] link here which includes a midleware for you to check if user is authorized to perform actions in your api.

It works by simply generating a JWT token on user login and returning that token to angular where you would store that token in your front end state file.

So on each request towards your backend you sent the JWT TOKEN which then the JWT middleware will check if user is "logged in" to perform a specific action.