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:

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

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 (' user ', 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?

Custom Authenticator: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 (incoming session included) * @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) {Ember.$.ajax ( {url:authurl, type: ' POST ', data: {email:credentials.identification, pas Sword:credentials.password}). Then (function(response)                {if (Response.login = = = ' Success ') {Resolve ({is_login:true});            }}, 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 attack            },            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:

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

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

?? Specifically speaking:??

Header content is the value of the ' Xsrf-token ' cookie set by Laravel, Laravel attempts to read the header (' X-xsrf-token ') from each request and verifies that the TOKEN value is legitimate, and if the test passes, it is considered A secure request (this feature is implemented in laravel/app/http/middleware/verifycsrftoken.php).

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

 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-&gt        ; Auth->check ()) {return $next ($request);     } abort (403, ' unauthorized action. ');     Throws an exception that is caught and processed by the front end}/** * Determine if the request has a URI of that should pass through auth verification. * * @param \illuminate\http\request $request * @return BOOL */protected function Shouldpassthrough ($requ EST) {foreach ($this->include as $include) {if ($request->is ($include)) {Retu            RN 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:

 Middleware (' guest ', [' except ' = ' getlogout ']);    } Public Function Postlogin (Request $credentials)//Login {return $this->loguserin ($credentials);        } public Function Getlogout ()//Logout {auth::logout ();    return Response::json ([' logout ' = ' success ']);            The Public Function Postregister (Request $credentials)//Create and register a new user {$newUser = the "username";        $newUser->email = $credentials [' email '];            $newUser->password = bcrypt ($credentials [' Password ']);            $newUser->save ();    return $this->loguserin ($credentials); } protected function Loguserin (Request $credentials)//implement user Login {$loginData = [' Email ' + $cred            entials[' 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.

  • Related Article

    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.