So Laravel rewarded me for being an early adopter of their Micro-Framework Lumen by stripping it of Session and Cookie functionality, forcing me to rewrite code for several sites to use JWT authentication.
If you find yourself in the same spot, below is how is how I added JWT auth, of course in a very basic form as each site I am responsible for has custom integration.
Using Satellizer – https://github.com/sahat/satellizer for AngularJS, the setup was pretty simple:
//APP angular.module("app", ['satellizer','restangular']); //CONFIG angular.module("app").config(function($authProvider) { //PUTS TOKEN IN HEADER REQUESTS $authProvider.httpInterceptor = function() { return true; }; //NAME YOUR TOKEN $authProvider.tokenPrefix = 'appToken'; }); //APP CONTROLLER angular.module("app").controller('appCtrl', function($scope, $window, $rootScope, $auth, af) { //KEEP AUTH STATE IN SCOPE $scope.isAuth = false; //CREATE SIMPLE FUNCTION TO CHECK AUTH STATE $scope.isAuthenticated = function() { return $auth.isAuthenticated(); }; //SET AUTH STATE ON LOAD OF CONTROLLER $scope.isAuth = $scope.isAuthenticated(); }); //LOGIN angular.module("app").controller('loginCtrl', function($scope, $window, $rootScope, $auth, af) { $scope.un = null; $scope.pw = null; $scope.loginSubmit = function() { if ($scope.loginForm.$valid) { var data = {}; data.un = $scope.un; //USERNAME data.pw = $scope.pw; //PASSWORD var send = angular.toJson(data); //CALL RESTANGULAR METHOD FOR LOGIN return af.loginUser(data).then( function(d) { //SUCCESS if (d.return=='success') { $auth.setToken(d.token); //GET TOKEN FROM RESPONSE $window.location = '/'; //SET DESTINATION AFTER LOGIN } else { //HANDLE ERROR } return d; }); } } //LOGOUT angular.module("app").controller('logoutCtrl', function($scope, $window, $rootScope, $auth) { //SIMPLE LOGOUT AND REDIRECT //YOU MAY WANT TO WRAP THIS WITH LOGIC //TO CHECK IF LOGGED IN OR OTHER CRITERIA $auth.logout(); $window.location = "/"; //REDIRECT TO HOMEPAGE });
You may or may not have to do this, I did, so I am including it for you. This enables the “Bearer” JWT authentication token to pass through in each request.
#ADDED THESE TWO LINES TO MAKE JWT TOKENS WORK WITH LUMEN RewriteCond %{HTTP:Authorization} . RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] # Handle Front Controller... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L]
Using composer I installed the PHP-JWT – https://github.com/firebase/php-jwt library.
Here is example code in the controller to check, parse, encode and decode JWT tokens.
namespace App\Http\Controllers; use Illuminate\Http\Response; use Illuminate\Http\Request; use \Firebase\JWT\JWT; use Laravel\Lumen\Routing\Controller as BaseController; class YourController extends BaseController { //CREATED SOME PROTECTED VARS protected $raw_token; protected $token_key; protected $decoded_token; //PARSE REQUEST BEFORE ADVANCING function __construct(Request $r) { //GET JWT KEY SET IN THE .ENV FILE $this->token_key = $_ENV['JWT_KEY']; //CHECK THAT AUTHORIZATION INCLUDED //IN HEADER REQUEST if(null !== $r->header('authorization')) { //GET AUTHORIZATION PORTION $h = $r->header('authorization'); //BREAK IT IN TWO $t = explode(" ",$h); //GET RAW JWT TOKEN $this->raw_token = $t[1]; //SET DECODED TOKEN $this->decoded_token = JWT::decode($this->raw_token,$this->token_key,array('HS256')); } else { //RETURN ERROR RESPONSE OR REDIRECT //NOTE, MUST USE '->send()' OR THIS REQUEST //WILL PROCEED TO ROUTED FUNCTION return response()->json('error')->send(); } } //FUNCTION TO LOGIN USER CALLED FROM FRONT END RESTANGULAR //AND ROUTED HERE VIA THE ROUTES.PHP FILE function loginMyUser(Request $r) { //CHECK USER LOGIN REQUEST LOGIC if ($r->un && $r->pw) { $someVar = array(); //SET DATA YOU NEED ON THE FRONT END return response()->json(array('token'=>$this->setToken($someVar))); } } //INTERNAL FUNCTION TO SET TOKEN function setToken($someVar) { //GET JWT KEY SET IN .ENV FILE $JWT_KEY = $_ENV['JWT_KEY']; //CREATE ARRAY FOR JWT TOKEN $token = array( "iss" => "http://yoursite.com", //SET DOMAIN "aud" => "http://yoursite.com", //SET DOMAIN "iat" => strtotime("now"), //SET ACTIVATED TIME "exp" => strtotime("+ 1 week"), //SET EXPIRED TIME "public" => array("this"=>"can be easily decoded because it is stored as base64"), "private" => $this->encrypt($someVar) //SET ENCODED VALUES USING CUSTOM ENCRYPTION ); $jwt = JWT::encode($token, $JWT_KEY); return $jwt; }
If you need help or have questions please post them below, this took a bit of time to figure out, but once I did it was pretty easy simplify and replicate.
HTH
😉
one comment ( awaiting your reply! )
Hello.
I have one question, how do you tell Lumen to use the Controller for handling the login?
-- anmaur