這篇文章將為大家詳細講解有關怎么在laravel8中使用dingo與jwt鑒權,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
dingo api包是給laravel和lumen提供的Restful的工具包,它可以與jwt組件一起配合快速的完成用戶認證,同時對于數據和運行過程中所產生的異常能夠捕獲到并且可以做出對應的響應。
主要功能:
Router Version 路由版本管理
http Exception 異常處理
response transform 轉化響應格式
在laravel根目錄下通過composer進行dingo擴展包的安裝,具體命令如下:
composer require dingo/api
使用以下命令可以發布 API 的配置文件到 config 文件下:
php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"
關于dingo的api配置信,我們可以在.env文件中進行配置
# dingo # API_SUBTYPE —— 項目的簡稱; API_SUBTYPE=lms # API_PREFIX —— 與 API_DOMAIN 二選一,路由的前綴,例如設置為 api API_PREFIX=api # 定義版本 API_VERSION=v1 # 是否開啟調試模式 API_DEBUG=true
關于dingo的詳細配置請查看相關文檔:https://learnku.com/docs/dingo-api/2.0.0/Configuration/1444
jwt全稱JSON Web Tokens ,是一個非常輕巧的規范,這個規范允許我們使用jwt在用戶和服務器之間傳遞安全可靠的信息,他的主要使用場景為:認證與數據交換
在laravel根目錄下通過composer進行jwt擴展包的安裝,具體命令如下:
composer require tymon/jwt-auth
使用以下命令可以發布 API 的配置文件到 config 文件下:
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
在.env文件中生成jwt加密秘鑰,具體命令如下:
php artisan jwt:secret
修改config/api.php配置
'auth' => [ 'jwt' => 'Dingo\Api\Auth\Provider\JWT', ],
修改config/auth.php配置
'defaults' => [ #注:這里修改改了默認的配置,默認是web 'guard' => 'api', 'passwords' => 'users', ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'jwt', 'provider' => 'users', 'hash' => false, ], ],
關于jwt的詳細配置請查看相關文檔:https://jwt-auth.readthedocs.io/en/develop/
創建RefreshToken中間件,用于令牌過期刷新
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
class RefreshToken extends BaseMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
// 檢查此次請求中是否帶有 token,如果沒有則拋出異常。
$this->checkForToken($request);
// 使用 try 包裹,以捕捉 token 過期所拋出的 TokenExpiredException 異常
try {
// 檢測用戶的登錄狀態,如果正常則通過
if ($this->auth->parseToken()->authenticate()) {
return $next($request);
}
throw new UnauthorizedHttpException('jwt-auth', '未登錄');
} catch (TokenExpiredException $exception) {
// 此處捕獲到了 token 過期所拋出的 TokenExpiredException 異常,我們在這里需要做的是刷新該用戶的 token 并將它添加到響應頭中
try {
// 刷新用戶的 token
$token = $this->auth->refresh();
// 使用一次性登錄以保證此次請求的成功
Auth::guard('api')
->onceUsingId($this->auth->manager()
->getPayloadFactory()
->buildClaimsCollection()
->toPlainArray()['sub']);
} catch (JWTException $exception) {
// 如果捕獲到此異常,即代表 refresh 也過期了,用戶無法刷新令牌,需要重新登錄。
throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
}
}
// 在響應頭中返回新的 token
return $this->setAuthenticationHeader($next($request), $token);
}
}User模型需要實現兩個方法:getJWTIdentifier()和getJWTCustomClaims()
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
public $table = "user";
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password','phone','status','create_time','addr_id'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
// 'email_verified_at' => 'datetime',
];
/**
* 指示是否自動維護時間戳
*
* @var bool
*/
public $timestamps = false;
public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return [];
}
}
?>創建UserController用于鑒權等相關操作
<?php
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use App\Models\User;
use Dingo\Api\Routing\Helpers;
use Illuminate\Http\Request;
class UserController extends Controller
{
use Helpers;
public function __construct()
{
//除去token驗證的方法
$this->middleware('refresh.token', [
'except' => [
'login',
],
]);
}
/**用戶登錄
* @param Request $request
* @return \Illuminate\Http\JsonResponse|void
*/
public function login(Request $request)
{
$phone = $request->get('phone');
$user = User::where('phone', $phone)->first();
// //attempt貌似無法驗證其他字段,如需用其他字段鑒權使用login()
// $credentials = request(['name','password']);
// if (!$token = auth()->attempt($credentials)) {
// return response()->json(['error' => 'Unauthorized'], 401);
// }
//只要是user實例就可以通過login鑒權
if (! $token = auth()->login($user)) {
return response()->json([
"restful" => false,
"message" => "賬號錯誤",
]);
}
//獲取用戶信息
$user = $this->user();
$key = "user::info::".$user->id;
//Redis緩存用戶信息3600秒
Redis::set($key,serialize($user->original),"EX",3600);
return $this->respondWithToken($token);
}
/**獲取用戶
* Get the authenticated User.
*
* @return \Illuminate\Http\JsonResponse
*/
public function user()
{
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" => "退出成功"]);
}
/**用戶登錄狀態刷新
* Refresh a token.
* @return \Illuminate\Http\JsonResponse
*/
public function refresh()
{
return $this->respondWithToken(auth()->refresh());
}
/**返回值
* @param $token
* @return array
*/
protected function respondWithToken($token)
{
return [
'access_token' => $token,
'token_type' => 'Bearer',
'expires_in' => auth()->factory()->getTTL() * 60,
'restful' => true
];
}
}關于怎么在laravel8中使用dingo與jwt鑒權就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。