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 (' 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:
Add a ' X-xsrf-token ' header for each AJAX request
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)