使用tymon/jwt-auth包(https://packagist.org/packages/tymon/jwt-auth)
1、安裝
composer require tymon/jwt-auth
2、發布配置,運行以下命令以發布包配置文件:您現在應該有一個config/jwt.php文件,允許您配置此包的基礎知識。
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
3、生成秘鑰
php artisan jwt:secret
這將.env使用類似的內容更新您的文件JWT_SECRET=foobar
這是將用於簽署您的令牌的密鑰。這究竟如何發生將取決於您選擇使用的算法。
4、更新您的用戶模型
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class TestUser extends Authenticatable implements JWTSubject
{
use Notifiable;
public $timestamps = false;
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* @return mixed
*/
public function getJWTIdentifier()
{
// TODO: Implement getJWTIdentifier() method.
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
並新建test_user表
CREATE TABLE `test_users` ( `id` int NOT NULL AUTO_INCREMENT, `phone` char(11) COLLATE utf8mb4_general_ci NOT NULL, `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `sex` tinyint NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
5、配置身份驗證保護
注意:這僅在您使用 Laravel 5.2 及更高版本時有效。
在該config/auth.php文件中,您需要進行一些更改以配置 Laravel 以使用jwt防護來支持您的應用程序身份驗證。
對文件進行以下更改:
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
...
'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
這里我們告訴api守衛使用jwt驅動程序,我們將api守衛設置為默認值。
我們現在可以使用 Laravel 內置的 Auth 系統,由 jwt-auth 完成幕后工作!
6、添加一些路由,使用了auth.jwt自定義的中間件
Route::post('login', [\App\Http\Controllers\TestUserController::class, 'login']);
Route::post('register', [\App\Http\Controllers\TestUserController::class, 'register']);
Route::group(['middleware' => ['auth.jwt']], function () {
Route::get('logout', [\App\Http\Controllers\TestUserController::class, 'logout']);
Route::get('user', [\App\Http\Controllers\TestUserController::class, 'getAuthUser']);
Route::get('refresh', [\App\Http\Controllers\TestUserController::class, 'refresh']);
});
7、創建控制器
php artisan make:controller TestUserController
8、添加以下內容
<?php
namespace App\Http\Controllers;
use App\Http\Response\BizFailResponse;
use App\Http\Response\BizSuccessResponse;
use App\Library\DataChecker;
use App\Models\TestUser;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\JWTAuth;
class TestUserController
{
public function register(Request $request)
{
$params = $request->input();
DataChecker::requireExpectParamIsNonEmptyStr($params, 'phone');
DataChecker::requireExpectParamIsNonEmptyStr($params, 'sex');
DataChecker::requireExpectParamIsNonEmptyStr($params, 'password');
$userInfo = TestUser::query()->where('phone', $params['phone'])->get()->toArray();
if (!empty($userInfo)){
return BizFailResponse::makeWithMsg("該賬號{$params['phone']}已被注冊");
}
$user = new TestUser();
$user->phone = $params['phone'];
$user->sex = $params['sex'];
$user->password = bcrypt($params['password']);
$user->save();
return BizSuccessResponse::makeWithData($user);
}
public function login(Request $request)
{
$input = $request->only('phone', 'password');
$jwt_token = null;
if (!$jwt_token = auth()->attempt($input)) {
return BizFailResponse::makeWithMsg('賬號或者密碼錯誤');
}
return BizSuccessResponse::makeWithData(['token'=>$jwt_token]);
}
public function logout(Request $request)
{
try {
auth()->invalidate();
return BizSuccessResponse::makeWithMsg('登出成功');
} catch (JWTException $exception) {
return BizFailResponse::makeWithMsg('登出失敗');
}
}
public function refresh(){
return BizSuccessResponse::makeWithData(['token'=>auth()->refresh()]);
}
public function getAuthUser(Request $request)
{
$user = auth()->user();
return response()->json(['user' => $user]);
}
}
9、新建中間件,支持token校驗和過期自動刷新
php artisan make:middleware AuthJwtTokend
代碼如下:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
/**
* 驗證token,並且過期自動刷新
* Class AuthJwtToken
* @package App\Http\Middleware
*/
class AuthJwtToken extends BaseMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
$this->checkForToken($request);
try {
if ($this->auth->parseToken()->authenticate()){
return $next($request);
}
throw new UnauthorizedHttpException('jwt-auth', '該用戶未登錄');
}catch (TokenExpiredException $e){
try {
$token = $this->auth->refresh();
Auth::guard('api')->onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);
// 在響應頭中返回新的 token
return $this->setAuthenticationHeader($next($request), $token);
}catch (JWTException $e) {
throw new UnauthorizedHttpException('jwt-auth', $e->getMessage());
}
}
}
}
10、注冊自定義中間件
App\Http\Kernel中$routeMiddleware新增
// 自定義中間件 'auth.jwt' => AuthJwtToken::class
11、訪問注冊、登錄、登出、獲取用戶信息等接口
