JWT achieve API-based user authentication

JWT-Auth implemented based authentication API

 

If you want to understand the principles of its Token generation algorithm, please refer to the relevant information on their own

Some need to be mentioned:

  • Use existing session problems:

    • session and cookie to solve the stateless http program. the user session status information stored in the server, is saved in Cookie JSESSIONID, request the server, the server reads JSESSIONID to determine the user's identity information, and the session + cookie used in the restful damaged the interface thereof "stateless" feature , session runtime are stored in memory, and with the increase of the authenticated user, server spending will be significantly increased. This is the restful "stateless" to solve the problem most committed. If a session, then there is no point in restful

    • session reduces the scalability of the system. After user authentication, the server doing the authentication record, if authenticated records are stored in memory, then this means that next time the user requests also have to request resources on this server, so as to get the authorization, so distributed on the application, the corresponding limits the ability of the load balancer. This also means that limits the scalability of the application

    • cookie unsafe, can easily lead to cross-site request forgery attack (CSRF)

  • token problems:

    • For example, how to determine the expiration time of the token? If the token's validity period is too short, it is likely to cause the user with the use of the situation is dropped, degrade the user experience. But now it seems as if there is no good way and can only try to extend the validity of the token, or every other front-end server to automatically request a token

  • JWT-Auth of token-based verification system

    (Pro-test, I hope this little article to let everyone into the pit)

  1. Running software version

    • laravel 5.5

  2. Installation JWT-Auth extended package

    composer require tymon/jwt-auth "1.5.*"

  3. After the installation in the configuration file config/app.php to add a registered service providers and aliases:

    ...
    'providers' => [
        ...
        Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,
    ]
    ...
    'aliases' => [
        ...
        'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
    ]
    

      

  4. Published resources

    php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
  5. Run the following commands to generate the key keyin the generation of config/jwt.php the

    // If the running error, suggesting ERROR: Method Tymon \ JWTAuth \ Commands \ JWTGenerateCommand :: handle () does not exist, the fire vendor \ tymon \ jwt-auth \ src \ Commands \ JWTGenerateCommand.php file () method modified to handle () to generate normal keys 
    php artisan jwt: generate

     

  6. Edited  app/Http/Kernel.php to add  jwt.auth and  jwt.refresh to route application middleware array:

    protected $routeMiddleware = [
        ...
        'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
    //    'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
    ];
    

      

  7. JWTAuth Middleware itself \Tymon\JWTAuth\Middleware\GetUserFromToken contains a verification token is generated for all kinds of situations, and the exception thrown. The following is the underlying validation class GetUserFromToken::class:

    // file_path : vendor\tymon\jwt-auth\src\Middleware\GetUserFromToken.php
    <?php
    ​
    /*
     * This file is part of jwt-auth.
     *
     * (c) Sean Tymon <[email protected]>
     *
     * For the full copyright and license information, please view the LICENSE
     * file that was distributed with this source code.
     */
    ​
    namespace Tymon\JWTAuth\Middleware;
    ​
    use Tymon\JWTAuth\Exceptions\JWTException; //验证异常类
    use Tymon\JWTAuth\Exceptions\TokenExpiredException;//token过期异常验证类
    ​
    class GetUserFromToken extends BaseMiddleware
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, \Closure $next)
        {
            if (! $token = $this->auth->setRequest($request)->getToken()) {
                return $this->respond('tymon.jwt.absent', 'token_not_provided', 400);
            }
    ​
            try {
                $user = $this->auth->authenticate($token);
            } catch (TokenExpiredException $e) {
                return $this->respond('tymon.jwt.expired', 'token_expired', $e->getStatusCode(), [$e]);
            } catch (JWTException $e) {
                return $this->respond('tymon.jwt.invalid', 'token_invalid', $e->getStatusCode(), [$e]);
            }
    ​
            if (! $user) {
                return $this->respond('tymon.jwt.user_not_found', 'user_not_found', 404);
            }
    ​
            $this->events->fire('tymon.jwt.valid', $user);
    ​
            return $next($request);
        }
    }
    

      

     

    Among them, calling the respond method in the vendor\tymon\jwt-auth\src\Middleware\BaseMiddleware.phpfile

     /**
         * Fire event and return the response.
         *
         * @param  string   $event
         * @param  string   $error
         * @param  int  $status
         * @param  array    $payload
         * @return mixed
         */
        protected function respond($event, $error, $status, $payload = [])
        {
            $response = $this->events->fire($event, $payload, true);
    ​
            return $response ?: $this->response->json(['error' => $error], $status);
        }
    

      

    You can see that when the abnormal need to return an error message will be accompanied returned a fire event warning event object, not detailed here.

  8. By the underlying code, you can understand that if we want to customize the authentication methods they need, these can be GetUserFromToken::class copied to the middleware our own custom content. such as:

    • To verify the creation of custom middlewareApp\Http\Middleware\JwtAuth.php

      php artisan make:middleware JwtAuth

       

    • After all the copy to the custom of the middleware, the middleware needs to check whether the class is fully applied, the namespace is correct and so, the need for verification check, definable as required.

      // demo 
      namespace App\Http\Middleware;
      ​
      use Tymon\JWTAuth\Exceptions\JWTException;
      use Tymon\JWTAuth\Exceptions\TokenExpiredException;
      use Closure;
      use Tymon\JWTAuth\Middleware\BaseMiddleware;
      ​
      class JwtAuth extends BaseMiddleware
      {
          public function handle($request, \Closure $next)
          {
              if (! $token = $this->auth->setRequest($request)->getToken()) {
                  return $this->respond('tymon.jwt.absent', 'token_not_provided', 400);
              }
      ​
              try {
                  $user = $this->auth->authenticate($token);
              } catch (TokenExpiredException $e) {
                  return $this->respond('tymon.jwt.expired', 'token_expired', $e->getStatusCode(), [$e]);
              } catch (JWTException $e) {
                  return $this->respond('tymon.jwt.invalid', 'token_invalid', $e->getStatusCode(), [$e]);
              }
      ​
              if (! $user) {
                  return $this->respond('tymon.jwt.user_not_found', 'user_not_found', 404);
              }
      ​
              $this->events->fire('tymon.jwt.valid', $user);
      ​
              return $next($request);
          }
      }
      

        

    • Defined after the completion of custom middleware into app\Http\Kernel.phpmiddleware array.

       protected $routeMiddleware = [
          ...
              //'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
              'jwt.auth_self' => \App\Http\Middleware\JwtAuth::class
          ];
      

        

    • After adding Well, you can in routes/api.php to verify control of the need to control the routing api

      Group :: the Route ([ 'Middleware' => 'jwt.auth_self'], function () { 
          // need to control the routing api 
          // code ... 
      });
      

        

  9. We can now verify the token of the routing request, and then the next we need to generate this token, so that subsequent access request routing middleware carries this token verification can be achieved. To mention here the installation JWT-Authprocedure generated configuration fileconfig/jwt.php

    ? <PHP 
        return [ 
        ... 
        / * 
        | --------------------------------------- ----------------------------------- 
        | the User Model namespace 
        | ---------- -------------------------------------------------- -------------- 
        | 
        | the Specify the user at the Full namespace to your Model. 
        | EG 'Acme \ Entities \ the user' 
        | 
        * / 
        // set your user model, comes with default laravel Model of the User 
        'User' => 'the App \ the User', 
    ]
    

      

    If demand requires, you can modify the configuration file in the user mode , but the configuration of model the need to reference Illuminate\Foundation\Auth\User as Authenticatable, and inheritance, writing and User modelconsistent

  10. Specific requests a login and access token information, logout and other functions to achieve, you can refer to this article

    Laravel 5 using JWT (Json Web Token) Based on the user authentication API , here simply referred to the conventional method of token on its

    <? PHP 
        namespace App \ Http \ the Controller; 
        
        use Tymon \ JWTAuth \ JWTAuth; 
        
        class Auth { 
            public function the Test (JWTAuth $ JWTAuth) { 
                
                // get token request carries the 
                $ token = $ JWTAuth -> getToken (); 
                // get token of the user information 
                $ = $ JWTAuth the user -> parseToken () -> the authenticate (); 
                // destroy the generated token 
                $ JWTAuth-> setToken ($ JWTAuth-> getToken ()) -> the invalidate (); 
                // custom build token, if desired 
                $ JWTAuth-> setToken ( 'foo.bar.baz'); 
            } 
        }
    

      

     

Guess you like

Origin www.cnblogs.com/rianley/p/11971233.html