laravel8 jwt多使用者認證

人生起落尋常事,花開花謝皆是春發表於2021-03-30
  1. 本文只用作記錄

一、下載jwt

github.com/tymondesigns/jwt-auth/w...
composer require tymon/jwt-auth

釋出配置檔案

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

二、生成jwt秘鑰

php artisan jwt:secret 

三、配置guard

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

        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
        ],

        'admin' => [
            'driver' => 'jwt',
            'provider' => 'admins'
        ]
    ],

四、配置providers

'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],

         'admins' => [
             'driver' => 'eloquent',
             'model' => App\Models\Admin::class,
         ],
    ],

五、生成jwt 中介軟體

php artisan make:middleware JWTRoleAuth 

六、配置jwt中介軟體

use Closure;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;

class JWTRoleAuth
{
    public function handle($request, Closure $next)
    {
        try {
            if (! $user = JWTAuth::parseToken()->authenticate()) {  //獲取到使用者資料,並賦值給$user
                return response()->json([
                    'code' => 1004,
                    'message' => '無此使用者'

                ], 404);
            }
            return $next($request);

        } catch (TokenExpiredException $e) {

            return response()->json([
                'code' => 1003,
                'message' => 'token 過期' ,
            ]);

        }  catch (TokenInvalidException $e) {
            return response()->json([
                'code' => 1002,
                'message' => 'token 無效',
            ]);

        } catch (JWTException $e) {

            return response()->json([
                'code' => 1001,
                'message' => '缺少token' ,
            ]);
        }
    }
}

七、編輯模型

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;


class Admin extends Authenticatable implements JWTSubject
{
    use HasFactory, Notifiable;

    protected $table="admins";


    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * 獲取會儲存到 jwt 宣告中的標識
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * 返回包含要新增到 jwt 宣告中的自定義鍵值對陣列
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return ["role"=>"admin"];
    }
}

八 、編寫程式碼測試

如果你是api auth:api
如果你是admin auth:admin

use App\Http\Controllers\Controller;
use App\Service\Api\RegisterService;
use Illuminate\Http\Request;

class LoginController extends Controller
{

    /**
     * @var RegisterService
     */

    private $registerService;

    /**
     * LoginController constructor.
     * @param RegisterService $registerService
     */
    public function __construct(RegisterService  $registerService)
    {
        $this->registerService = $registerService;
        $this->middleware("auth:api",['except' => ['login', 'register',"logout"]]);
    }

    public function register(Request $request)
    {
        $name = $request->input("name");

        $email = $request->input("email");

        $password = $request->input("password");

        $data = $this->registerService->register($name,$email,$password);

        if ($data){
            return $this->success("0",$data,"註冊成功");
        } else {
            return $this->error("425",$data,"註冊失敗");
        }

    }

    public function login(Request $request)
    {
        $credentials = request(['name', 'password']);

        if (! $token = auth("api")->attempt($credentials)) {
            $this->error("0",[],"登入失敗");
        }

        return $this->success("1",$this->respondWithToken($token),"登入成功");
    }

    /**
     * Refresh a token.
     * 重新整理token,如果開啟黑名單,以前的token便會失效。
     * 值得注意的是用上面的getToken再獲取一次Token並不算做重新整理,兩次獲得的Token是並行的,即兩個都可用。
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->success('0',$this->respondWithToken(auth('api')->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('api')->factory()->getTTL() * 60
        ]);
    }

    /**
     * 使用者退出登入
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth('api')->logout();

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

    public function me()
    {
        $data = auth("api")->user();
        return $this->success("0",$data,"查詢成功");
    }
}

九、測試

測試註冊

測試登入

測試我的資訊

測試登出

十、我的環境是

php7.4.16 + nginx1.19.8 + mysql8.0.23 + laravel8.34.0

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

相關文章