User authorization system based on Laravel (5.1) & Ember.js (1.13.0)

Source: Internet
Author: User

Laravel itself provides a complete user authorization solution, and for PHP-driven multi-page applications, Laravel can perfectly address user authorization issues. But in the SPA, Laravel degenerated into an API server, where page Routing and form submissions were completely controlled by the front-end framework, and faced 2 problems:

  1. How do I implement page access control on the front end?

  2. How do I authorize an AJAX request?


How do I implement page access control on the front end?

Ember.js 1.13.0 did not provide authentication functionality, I used a third-party extension called Ember-simple-auth. This is its Github homepage:

Https://github.com/simplabs/ember-simple-auth

First install the extension in your EMBER-CLI project root directory:

Ember Install Ember-cli-simple-auth

It is then configured in the Ember/config/environment.js file, and the specific configuration options are detailed in the documentation, and my configuration is as follows:

ember/config/environment.jsenv[' Simple-auth ' = {authorizer: ' authorizer:custom '//I used a custom authorization module};

Ember-simple-auth defines a series of mixin classes that, as long as your route inherits a certain mixin, obtains some of its predefined behaviors or functions. For example, my ember/app/routes/application.js content is as follows:

Ember/app/routes/application.js import applicationroutemixin from ' simple-auth/mixins/application-route-mixin ';            Export default Ember.Route.extend (Applicationroutemixin, {actions: {invalidatesession:function () {        This.get (' Session '). Invalidate (); }    }});

Application-route-mixin has predefined a series of actions. When an event on the session is triggered, the corresponding action is called to handle the event. You can also override these methods in Ember/app/routes/application.js's own action (Ember-simple-auth maintains a session object in the local localstorage, It holds all the licensing information generated by the front end ).

Then, add the Authenticated-route-mixin in a page route that can only be accessed by an authorized user:

Ember/app/routes/user.js import authenticatedroutemixin from ' simple-auth/mixins/authenticated-route-mixin '; Export default Ember.Route.extend (authenticatedroutemixin,{model:function (params) {return This.store.find (' Us    Er ', params.user_id); }});

Authenticated-route-mixin guarantees that only authorized users can access/user. If not authorized, the default is redirected to/login. So you need to add Unauthenticated-route-mixin in Ember/app/routes/login.js:

Ember/app/routes/login.js import unauthenticatedroutemixin from ' Simple-auth/mixins/unauthenticated-route-mixin ' ; Export default Ember.Route.extend (unauthenticatedroutemixin);

Unauthenticated-route-mixin ensures that the path does not need to be authorized and accessible, which is reasonable for/login.


How do I authorize an AJAX request?

ember/app/authenticators/custom.js

 ember/app/authenticators/custom.jsimport Base from  ' Simple-auth/authenticators/base '; Export default base.extend ({    /**     * check  auth state of frontend     *     *   @param  data  (data included in incoming session)      *  @returns  { Es6promise.promise}     */    restore: function (data)  {         return new ember.rsvp.promise (function (Resolve,  reject)         {             if  ( data.is_login ) {                 resolve (data);             }            else{                 reject ();             }        });    },     /**     * permission to login by frontend      *     *  @param  obj credentials      *  @returns  {ES6Promise.Promise}     */     authenticate: function (Credentials)  {        var  authUrl = credentials.isLogin ?  '/auth/login '  :  '/auth/register '          return new ember.rsvp.promise (Function (resolve,  Reject)  {   &Nbsp;        ember.$.ajax ({                 url:  authUrl,                 type:  ' POST ',                 data: { email:  credentials.identification, password: credentials.password }             }). Then (function (response)  {                 if (response.login ===  ' success ') {                      resolve ({ is_login : true });               &Nbsp; }            }, function (XHR,  status, error)  {                 reject (Xhr.responsetext);             });         });    },     /**     * permission to logout by frontend      *     *  @returns  {ES6Promise.Promise}      */    invalidate: function ()  {         return new ember.rsvp.promise (function (resolve)  {             ember.$.ajax ({                 url:  '/auth/logout ',                 type:  ' GET '              }). Then (function (response)  {                 if (response.logout ===  ' success ') {                     resolve ();                 }             });         });     }});

Restore, authenticate, invalidate 3 functions are used to obtain authorization, authorization, cancellation of authorization, respectively.

Custom Authorizer: Ember/app/authorizers/custom.js

 ember/app/authorizers/custom.jsimport Base from  ' simple-auth/authorizers/base '; export  default base.extend ({    authorize: function (jqXHR, requestOptions)     {        var _this = this;         ember.$.ajaxsetup ({             headers:             {                 ' X-XSRF-TOKEN ':  ember.$.cookie (' Xsrf-token ')     //  prevent cross-domain attacks              },             Complete : function (response, state)              {                //  Check the authorization status of the server                 if ( Response.status===403 && _this.get (' Session '). IsAuthenticated)                    {                     _this.get (' Session ') . Invalidate ();                 }            }         });     });

The authorize function does two things:

    1. Add a ' X-xsrf-token ' header for each AJAX request

    2. Check the authorization status returned by the server and do the processing

? ? Concretely speaking:? ?

Header content is the value of the ' Xsrf-token ' cookie set by Laravel, Laravel will attempt to read the header ('x-xsrf-token') from each request and verify that the TOKEN value is legitimate if the This is considered a secure request (this function is implemented in laravel/app/http/middleware/verifycsrftoken.php).

Then, create a new middleware (middleware) in Laravel, and I'll name it verifyauth:

<?php// laravel/app/Http/Middleware/VerifyAuth.phpnamespace App\Http\Middleware;use Closure; use illuminate\contracts\auth\guard;class verifyauth{    protected  $include  = [' api/* '];    //  need to do permission verification of  url    protected   $auth     public function __construct (guard  $auth)      {         $this->auth =  $auth;     }    /**     * Handle an incoming  request.     *     *  @param   \illuminate\http \request   $request      *  @param   \Closure   $next      *  @abort   403     *  @return    mixed     */    public function handle ($request, closure  $next)     {        if (  $this->shouldpassthrough ( $request)  | |   $this->auth->check ()  )         {             return  $next ($request);         }        abort (403,  ' Unauthorized  Action. ');      //throws an exception, captured and processed by the front end     }    /**      * Determine if the request has a URI that  should pass through auth verification.     *      *  @param   \Illuminate\Http\Request   $request       *  @return  bool     */    protected function  Shouldpassthrough ($request)     {        foreach   ($this->include as  $include)  {             if  ($request->is ($include))  {                 return false;             }        }         return true;    }}

It only authenticates the API request because the AUTH request is a permission operation, and other requests are rerouted to the front end as invalid requests, or an error is thrown. If a request is not authorized, the server throws a 403 error reminder that the front end requires the user to log in or register.

Finally, implement all the authorization logic in laravel\app\http\controllers\auth\authcontroller.php:

<?phpnamespace app\http\controllers\auth;use app\user;use validator;use response;use  auth;use illuminate\http\request;use app\http\controllers\controller;use illuminate\ foundation\auth\throttleslogins;use illuminate\foundation\auth\authenticatesandregistersusers;class  Authcontroller extends controller{    use authenticatesandregistersusers,  ThrottlesLogins;    protected  $remember  = true;     //  whether long-term remember logged in User     public function __construct ()      {         $this->middleware (' guest ',  [' except '  =>   ' getlogout ']);     }    public function postlogin ( request  $credentials)     //  login     {         return&nbSP; $this->loguserin ($credentials);     }    public function  getlogout ()     //  logout     {         auth::logout ();         return response::json ([' Logout ' = ' success ']);    }    public function  Postregister (request  $credentials)     //  Create and register a new user     {          $newUser  = new User;              $newUser->email =  $credentials [' Email '];          $newUser->password = bcrypt ($credentials [' Password ']);              $newUser->save ();             return  $this->loguserin ($credentials);    }             protected function loguserin (Request $ Credentials)     //  Enable user login     {          $loginData  = [' email '  =>  $credentials [' email '],  ' password '   =>  $credentials [' Password ']];             if  ( auth::attempt ($loginData,  $this->remember)  )          {            return response:: JSON ([' Login ' = ' success ']);        }         else        {             rEturn response::json ([' Login ' = ' failed ']);        }     }}


Summarize

Setting page access rights prevents unauthorized users from accessing pages that do not belong to him, but the front end is completely exposed to the user, so the user's authorization status must be maintained by the server. The front-end adds tokens for each AJAX request to prevent cross-domain attacks, and, on the other hand, checks if HTTP status code is a 403 permission error after each request returns and, if so, redirects to the login page to require the user to obtain authorization.

User authorization system based on Laravel (5.1) & Ember.js (1.13.0)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.