laravel API 里关于 JWT 的使用 — 不使用 laravel 自带的 User 模型

备注:该文档适合 laravel 5.5 以上的!
备注:该文档适合 laravel 5.5 以上的!
备注:该文档适合 laravel 5.5 以上的!

第一步:创建一个 laravel 新项目;

composer create-project --prefer-dist laravel/laravel apiJWT

第二步:进入新新项目;

cd apiJWT

第三步:安装 tymon/jwt-auth;

composer require tymon/jwt-auth

第四步:发布,这条命令会在 config 下增加一个 jwt.php 的配置文件;

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

第五步:在 .env 文件下生成一个加密密钥,如:JWT_SECRET=************;

php artisan jwt:secret

第六步:创建一个模型,并创建迁移文件;

php artisan make:model Models/Userinfo -m

第七步:修改 2020_07_28_172934_create_userinfos_table.php 迁移文件;

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUserinfosTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create( 'userinfos' , function( Blueprint $table ) {
            $table->collation = 'utf8mb4_general_ci';
            $table->engine = 'InnoDB';

            // 将 INTEGER 类型的字段设置为自动递增的主键
            $table->increments( 'userid' )->comment( '用户 ID 唯一,自增,主键' );
            $table->char( 'username' , 20 )->comment( '用户昵称' );
            $table->char( 'password' , 255 )->comment( '用户密码' );
            $table->char( 'email' , 100 )->comment( '用户邮件' );
            $table->unsignedTinyInteger( 'gender' )->default( 0 )->comment( '用户性别(性别 0:未知、1:男、2:女)' );
            $table->char( 'mobile' , 11 )->comment( '用户的手机号码' );
            $table->timestamps();

                            $table->index( [ 'username' ] );
            $table->index( [ 'email' ] );
            $table->index( [ 'gender' ] );
        } );

        DB::statement( "ALTER TABLE `userinfos` comment '用户基本信息表'" );
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists( 'userinfos' );
    }
}

第八步:修改 Models/Userinfo.php 模型文件;(一定注意看中文注释);

<?php

    namespace App\Models;

    use Illuminate\Database\Eloquent\Model;
    use Tymon\JWTAuth\Contracts\JWTSubject;                // 使用 JWTAuth 的命名空间

    class Userinfo extends Model implements JWTSubject    // 这里别忘了加
    {
    use Notifiable;          
          /**
       * Get the identifier that will be stored in the subject claim of the JWT.
       *
       * @return mixed
       */

      public function getJWTIdentifier()
      {
       return $this->getKey();
      }

      /**
       * Return a key value array, containing any custom claims to be added to the JWT.
       *
       * @return array
       */
      public function getJWTCustomClaims()
      {
       return [];
      }
  }

第九步:执行迁移文件;

php artisan migrate

第十步:修改 config/auth.php 文件,内容如下:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'jwt',           // 将原来的 token 改为 jwt 
        'provider' => 'users',
        'hash' => false,
    ],
],

第十一步:创建 token 控制器;

php artisan make:controller AuthController

第十二步:AuthController 控制器里的内容如下:

<?php

  namespace App\Http\Controllers;

  use Illuminate\Support\Facades\Auth;
  use App\Http\Controllers\Controller;

  use App\Models\Userinfo;
  use Illuminate\Http\Request;
  use Illuminate\Support\Facades\DB;
  use Tymon\JWTAuth\JWT;
  use Tymon\JWTAuth\JWTAuth;

  class AuthController extends Controller
  {
      /**
       * Create a new AuthController instance.
       *
       * @return void
       */
      public function __construct()
      {
          $this->middleware('auth:api', ['except' => ['login']]);
      }

      /**
       * Get a JWT via given credentials.
       *
       * @return \Illuminate\Http\JsonResponse
       */
      public function login()
      {
          $credentials = request(['email', 'password']);

          if (! $token = auth()->attempt($credentials)) {
              return response()->json(['error' => 'Unauthorized'], 401);
          }

          return $this->respondWithToken($token);
      }

      /**
       * Get the authenticated User.
       *
       * @return \Illuminate\Http\JsonResponse
       */
      public function me()
      {
          return response()->json(auth()->user());
      }

      /**
       * Log the user out (Invalidate the token).
       *
       * @return \Illuminate\Http\JsonResponse
       */
      public function logout()
      {
          auth()->logout();

          return response()->json(['message' => 'Successfully logged out']);
      }

      /**
       * Refresh a token.
       *
       * @return \Illuminate\Http\JsonResponse
       */
      public function refresh()
      {
          return $this->respondWithToken(auth()->refresh());
      }

      /**
       * Get the token array structure.
       *
       * @param  string $token
       *
       * @return \Illuminate\Http\JsonResponse
       */
      protected function respondWithToken($token)
      {
          return response()->json([
              'access_token' => $token,
              'token_type' => 'bearer',
              'expires_in' => auth()->factory()->getTTL() * 60
          ]);
      }
}

第十三步:在 routes/api.php 里增加路由;

Route::group([

      'middleware' => 'api',
      'prefix' => 'auth'

  ], function ($router) {

      Route::post('login', 'AuthController@login');
      Route::post('logout', 'AuthController@logout');
      Route::post('refresh', 'AuthController@refresh');
      Route::post('me', 'AuthController@me');

  });

第十四步:让我们使用 JWT 身份验证在 laravel 中写 Restful API 的逻辑。用户注册时需要姓名,邮箱和密码。那么,让我们创建一个表单请求来验证数据。通过运行以下命令创建名为 RegisterAuthRequest 的表单请求:

php artisan make:request RegisterAuthRequest

第十五步:它将在 app/Http/Requests 目录下创建 RegisterAuthRequest.php 文件。将下面的代码黏贴至该文件中。

<?php

  namespace App\Http\Requests;

  use Illuminate\Foundation\Http\FormRequest;

  class RegisterAuthRequest extends FormRequest
  {
      /**
       * 确定是否授权用户发出此请求
       *
       * @return bool
       */
      public function authorize()
      {
          return true;
      }

      /**
       * 获取应用于请求的验证规则
       *
       * @return array
       */
       public function rules()
       {
          return [
              'name' => 'required|string',
              'email' => 'required|email|unique:users',
              'password' => 'required|string|min:6|max:10'
          ];
      }
  }

配置项详解:

<?php

return [
/*
|--------------------------------------------------------------------------
| JWT Authentication Secret
|--------------------------------------------------------------------------
|
| 用于加密生成 token 的 secret
|
*/

'secret' => env('JWT_SECRET'),

/*
|--------------------------------------------------------------------------
| JWT Authentication Keys
|--------------------------------------------------------------------------
|
| 如果你在 .env 文件中定义了 JWT_SECRET 的随机字符串
| 那么 jwt 将会使用 对称算法 来生成 token
| 如果你没有定有,那么jwt 将会使用如下配置的公钥和私钥来生成 token
|
*/

'keys' => [

    /*
    |--------------------------------------------------------------------------
    | Public Key
    |--------------------------------------------------------------------------
    |
    | 公钥
    |
    */

    'public' => env('JWT_PUBLIC_KEY'),

    /*
    |--------------------------------------------------------------------------
    | Private Key
    |--------------------------------------------------------------------------
    |
    | 私钥
    |
    */

    'private' => env('JWT_PRIVATE_KEY'),

    /*
    |--------------------------------------------------------------------------
    | Passphrase
    |--------------------------------------------------------------------------
    |
    | 私钥的密码。 如果没有设置,可以为 null。
    |
    */

    'passphrase' => env('JWT_PASSPHRASE'),

],

/*
|--------------------------------------------------------------------------
| JWT time to live
|--------------------------------------------------------------------------
|
| 指定 access_token 有效的时间长度(以分钟为单位),默认为1小时,您也可以将其设置为空,以产生永不过期的标记
|
*/

'ttl' => env('JWT_TTL', 60),

/*
|--------------------------------------------------------------------------
| Refresh time to live
|--------------------------------------------------------------------------
|
| 指定 access_token 可刷新的时间长度(以分钟为单位)。默认的时间为 2 周。
| 大概意思就是如果用户有一个 access_token,那么他可以带着他的 access_token 
| 过来领取新的 access_token,直到 2 周的时间后,他便无法继续刷新了,需要重新登录。
|
*/

'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),

/*
|--------------------------------------------------------------------------
| JWT hashing algorithm
|--------------------------------------------------------------------------
|
| 指定将用于对令牌进行签名的散列算法。
|
*/

'algo' => env('JWT_ALGO', 'HS256'),

/*
|--------------------------------------------------------------------------
| Required Claims
|--------------------------------------------------------------------------
|
| 指定必须存在于任何令牌中的声明。
| 
|
*/

'required_claims' => [
    'iss',
    'iat',
    'exp',
    'nbf',
    'sub',
    'jti',
],

/*
|--------------------------------------------------------------------------
| Persistent Claims
|--------------------------------------------------------------------------
|
| 指定在刷新令牌时要保留的声明密钥。
|
*/

'persistent_claims' => [
    // 'foo',
    // 'bar',
],

/*
|--------------------------------------------------------------------------
| Blacklist Enabled
|--------------------------------------------------------------------------
|
| 为了使令牌无效,您必须启用黑名单。
| 如果您不想或不需要此功能,请将其设置为 false。
|
*/

'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),

/*
| -------------------------------------------------------------------------
| Blacklist Grace Period
| -------------------------------------------------------------------------
|
| 当多个并发请求使用相同的JWT进行时,
| 由于 access_token 的刷新 ,其中一些可能会失败
| 以秒为单位设置请求时间以防止并发的请求失败。
|
*/

'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),

/*
|--------------------------------------------------------------------------
| Providers
|--------------------------------------------------------------------------
|
| 指定整个包中使用的各种提供程序。
|
*/

'providers' => [

    /*
    |--------------------------------------------------------------------------
    | JWT Provider
    |--------------------------------------------------------------------------
    |
    | 指定用于创建和解码令牌的提供程序。
    |
    */

    'jwt' => Tymon\JWTAuth\Providers\JWT\Namshi::class,

    /*
    |--------------------------------------------------------------------------
    | Authentication Provider
    |--------------------------------------------------------------------------
    |
    | 指定用于对用户进行身份验证的提供程序。
    |
    */

    'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,

    /*
    |--------------------------------------------------------------------------
    | Storage Provider
    |--------------------------------------------------------------------------
    |
    | 指定用于在黑名单中存储标记的提供程序。
    |
    */

    'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,

],
];

打完收工!!

留下评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注