为了API的安全性,本次跟各位介绍透过JWT Token来帮API做身分验证,简单来说就是先让使用者登入来取得Token,接下来需使用得到的Token进行其他API的访问,并可以在程序当中透过Token来判别目前的使用者是谁.
$ sail composer require tymon/jwt-auth 1.*@rc
$ sail artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
$ sail artisan jwt:secret
<?php
namespace App\Models;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Models\Post;
class User extends Authenticatable implements JWTSubject
{
/**
* 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 [];
}
}
config/app.php
内注册两个Facade,为了是方便使用JWTAuth和JWTFactory的功能'aliases' => [
...
'JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth',
'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory',
],
config/auth.php
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
...
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
routes/api.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
Route::group(['prefix' => 'auth'], function () {
Route::post('login', [AuthController::class, 'login']);
Route::post('register', [AuthController::class, 'register']);
});
$ sail artisan make:controller AuthController
$ sail artisan make:service AuthService
$ sail artisan make:repository UserRepository
<?php
namespace App\Http\Controllers;
use App\Services\AuthService;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Facades\JWTAuth;
class AuthController extends Controller
{
protected $service;
public function __construct(AuthService $service)
{
$this->middleware('jwt.auth', ['except' => ['login', 'register']]);
$this->service = $service;
}
/**
* 登入取得Token
* @param Request $request
* @return JsonResponse
*/
public function login(Request $request)
{
$account = $request->input('account');
$password = $request->input('password');
$token = $this->service->login($account, $password);
if ($token !== false) {
$result = [
'token_type' => 'Bearer',
'access_token' => $token,
'expires_in' => auth('api')->factory()->getTTL() * 60
];
}
return response()->json($result);
}
/**
* 注册使用者
* @param Request $request
* @return JsonResponse
*/
public function register(Request $request)
{
$result = $this->service->register($request->all());
return response()->json($result);
}
}
JWTAuth::fromUser($user)
方法建立token,但token的建立不只一种,本范例这是基於User model返回instance产生token,好处是之後可以透过$user = Auth::guard('api')->user()
取得User model进行使用<?php
namespace App\Services;
use App\Repositories\UserRepository;
use Tymon\JWTAuth\Facades\JWTAuth;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Hash;
class AuthService
{
/**
* @var UserRepository
*/
protected $user_repository;
public function __construct(UserRepository $user_repository)
{
$this->user_repository = $user_repository;
}
public function login(string $account, string $password)
{
$user = $this->user_repository->searchUserByAccount($account);
// 密码不符
if (! Hash::check($password, $user->password)) {
// TODO error handler
dd('password not matched');
}
return JWTAuth::fromUser($user);
}
public function register(array $data)
{
$name = Arr::get($data, 'name');
$account = Arr::get($data, 'account');
$password = Arr::get($data, 'password');
$user = $this->user_repository->registerAccount($name, $account, $password);
return $user;
}
}
<?php
namespace App\Repositories;
use Exception;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
class UserRepository
{
/**
* 透过帐号搜寻特定使用者
*
* @param string $account 帐号
* @return mixed
*/
public function searchUserByAccount(string $account)
{
try {
return User::select(['*'])
->where('account', $account)
->first();
} catch (Exception $e) {
dd($e);
}
}
/**
* 建立使用者
*
* @param string $name 姓名
* @param string $account 帐号
* @param string $password 密码
* @return mixed
*/
public function registerAccount(string $name, string $account, string $password)
{
try {
return User::create([
'name' => $name,
'account' => $account,
'password' => Hash::make($password),
]);
} catch (Exception $e) {
dd($e);
}
}
}
设定完成後,如果之後建立的API希望透过token验证,可以在route处加上Route::middleware(['jwt.auth'])
如下
# /routes/api.php
Route::middleware(['jwt.auth'])->group(function () {
Route::group(['prefix' => 'user'], function () {
Route::get('/', [UserController::class, 'index']);
});
Route::group(['prefix' => 'post'], function () {
Route::post('/', [PostController::class, 'create']);
Route::get('/', [PostController::class, 'index']);
});
});
接下来使用Postman进行测试
先注册一个新的User
POST /auth/register
登入取得Token
POST /auth/login
当API需要Authentication时,Header处加上Authorization
以上就是这次Authorization的介绍,网路上有很多关於Jwt token的介绍非常的详细,这次是透过之前使用过的经验加上网路上爬文分享实务上的经验给大家,希望对大家有帮助
上一篇聊了从技术背景出发如何踏上追求人性之路, 这篇我想就我所知的部分, 聊聊如果是设计背景如何往这...
人脸辨识的技术可使用两种方式搭建云端上或边缘装置上,那要如何选择将系统搭在哪个架构上,就要先了解系统...
该文章同步发布於:我的部落格 昨天有提到会稍微介绍一下 allow method,其实在昨天的范例...
Group Managed ServiceAccounts (gMSA) 用途 AD网域的环境下,要...
前言 这次主要是更新我之前的笔记,那时候刚学习 JavaScript,对於一些结果可能不是很懂,刚好...