laravel 介面使用JWT(dingo)認證

wenreal發表於2020-10-10

主要總結下個人使用過程
1.下載外掛

composer require tymon/jwt-auth:1.0.*@dev

有的版本(5.8.35)在下載tymon/jwt-auth會同時下載dingo/api和更新其他外掛,如果沒有下載dingo/api,請執行下面命令  

composer require dingo/api    

有些版本(5.8.38)可能直接無法下載,
可在composer.json檔案的require新增
"dingo/api": "^2.3"
然後執行命令 composer update(會同時更新其他外掛)

2.生成新的配置檔案

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
// 這條命令會在 config 下增加一個 jwt.php 的配置檔案

php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"
//這條命令會在 config 下增加一個 api.php 的配置檔案

3.生成jwt秘鑰

php artisan jwt:secret //會在.env裡新增一行JWT_SECRET=秘鑰 秘鑰也可自定義

4.配置相關內容,這裡建議原來的配置是註釋而不是刪除
1).修改config/auth.php檔案裡的資訊

a.修改defaults的guards為
    'defaults'  =>  [
    //        'guard' => 'web',//原來的配置資訊
    //        'passwords' => 'users',//原來的配置資訊
    'guard'  =>  'api', 
    'passwords'  =>  'supplier',
    ],

b.在guards中修改或新增
    'guards'  =>  [
        'api'  =>  [
            'driver'  =>  'jwt',
            'provider'  =>  'api',
        ]
    ]

c.在providers 中修改或新增
    'providers'  =>  
        'api'  =>  [
            'driver'  =>  'eloquent',
            'model'  => App\Account::class,//可自定義,記得配置同步即可
            ],
        ]

2).

2).修改 app/Providers/AppServiceProvider.php檔案,在boot方法新增

    public function boot()
    {
        //驅動 將dingoh和jwt聯絡起來
        app('Dingo\Api\Auth\Auth')->extend('jwt', function ($app) {
            return new \Dingo\Api\Auth\Provider\JWT($app['Tymon\JWTAuth\JWTAuth']);
        });
    }

3).修改config/api.php檔案, 找到’auth’=>[]新增或修改,

    'auth' => [
        'jwt' => 'Dingo\Api\Auth\Provider\JWT',
    ],

4).修改config/app.php檔案,

a.在providers新增
    Dingo\Api\Provider\LaravelServiceProvider::class,
    Tymon\JWTAuth\Providers\LaravelServiceProvider::class,

b.在aliases新增
    'JWTAuth'  =>  'Tymon\JWTAuth\Facades\JWTAuth',
    'JWTFactory'  =>  'Tymon\JWTAuth\Facades\JWTFactory',

5).修改檔案 .env, 在最下面(個人習慣)新增

    API_PREFIX=api
    API_STANDARDS_TREE=vnd
    API_VERSION=v1
    API_DEBUG=false

5.新增BaseController檔案,內容如下

<?php
namespace App\Http\Controllers\API;
use Dingo\Api\Routing\Helpers;
use App\Http\Controllers\Controller;

class BaseController extends Controller
{
    //
    use Helpers;

    /****
     * BaseController constructor.
     */
    public function __construct()
    {

    }
}
//注意名稱空間的大小寫

6.新增登入介面的模型檔案,資訊同步 步驟 4->1)->c,也可不新增,使用已有的模型檔案.把裡面的表名和欄位名,改成自己的登入表及欄位名,內容參考如下.

<?php
namespace App;

use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authuser;

class Account extends Authuser implements JWTSubject
{
    use Notifiable;

    //定義表
    protected $table = "users";//修改為自己的登入表

    protected $hidden = ['remember_token'];
    // Rest omitted for brevity

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey(); /*自己可以定義的生成token的引數,這個用的是將主鍵加密*/
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
    protected $fillable = ['name','mobile','password'];
    //定義主鍵
    protected $primaryKey = "id";

}

7.新增介面檔案 ApiController.php,內容參考如下

<?php
namespace App\Http\Controllers\API;
use Encore\Admin\Facades\Admin;
use Illuminate\Support\Facades\DB;
use Tymon\JWTAuth\JWTAuth;
use Illuminate\Http\Request;
class ApiController extends BaseController
{
    protected $jwt;
    public function __construct(JWTAuth $jwt)
    {
        $this->jwt = $jwt;
    }

    public function login_jwt(Request $request)
    {
        $this->validate($request, [
            'username'    => 'required|max:255',
            'password' => 'required',
        ]);
        try {
            //驗證使用者是否存在,
    if(empty(admin_users::where('username',$request['username'])->first())){
               return self::return_('手機號未註冊',404);
            }
            //使用者與密碼是否正確
            if (! $token = $this->jwt->attempt($request->only('username', 'password'))) {
                return self::return_('使用者名稱或密碼錯誤',500);
            }
        } catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {

            return self::return_('登入過期',500);
        } catch (\Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {

            return self::return_('無效的token',500);
        } catch (\Tymon\JWTAuth\Exceptions\JWTException $e) {

            return self::return_('token未提交',500,$e->getMessage());
        }catch (\Exception $e){
            return self::return_('操作出錯',500,$e->getMessage());
        }
        $user=auth('api')->user();
        return self::return_('OK',200,$user);
    }
    // 返回資料
     private static function return_($errmsg='',$errcode=200,$data=[]){
         if(empty($data)){
             return ['errcode'=>$errcode,'errmsg'=>$errmsg];
         }else{
             return ['errcode'=>$errcode,'errmsg'=>$errmsg,'data'=>$data];
         }
     }
//測試介面
    public function test(){
        return 'test';
    }

}

8.修改路由api檔案routes/api.php ,內容可參考如下

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
//這裡的的介面,都是不需要認證的
Route::get('source', 'API\ApiController@source');//來源範圍

$api = app("Dingo\Api\Routing\Router");
$api->version('v1', function ($api) {
    $api->group(["namespace" => "App\Http\Controllers\API",'middleware'=>'jwt.auth'], function ($api) {
        //需要認證的介面放在這裡
        $api->get('test', 'ApiController@test');
    });

    $api->group(["namespace" => "App\Http\Controllers\API"], function ($api) {
        //不需要認證的介面放這裡或者寫在$api之外
        //使用dingo 外掛後,這裡 必須加一個介面,即使不存在的介面也行,否則所有介面都會報錯
        $api->post('login', 'ApiController@login_jwt');
    });
});

參考文件:blog.csdn.net/m0_37632915/article/...
內容基本都是參考的這個文件,不同的地方,主要是自己在使用過程出現的問題.

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章