本文最后更新于2022-08-24,已超过 1年没有更新,如果文章内容、图片或者下载资源失效,请留言反馈,我会及时处理,谢谢!
温馨提示:本文共4363个字,读完预计11分钟。
本文出处:https://learnku.com/articles/67696
系统相关情况:ubuntu + php7.4 + Laravel8
说明:最近在写JWT相关逻辑,参考这篇文章配置JWT,具体怎么配置,这里就不说了,这篇文章主要针对token的验证,通过中间件来实现。
补充一下,我的项目是两个模块的,路由api那个我同事再用,我是后台所以新增一个admin路由文件,用户体系也不同,他是user表,我是user_admin表,所以第一步先配置我的模块的信息
第一步,配置自己的guards
在config/auth.php里面的guards数组新增admin键值:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'apiusers',
],
'admin' => [ //admin模块
'driver' => 'jwt',
'provider' => 'admin',
],
],
然后我下面找providers数组,新增admin模块:
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'apiusers' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admin' => [ //admin模块
'driver' => 'eloquent',
'model' => App\Models\UserAdmin::class, //admin的用户模型
],
],
第二步,生产中间件
通过命令:
php artisan make:middleware AuthAdminJwt
AuthAdminJwt类里面内容如下:
<?php
namespace App\Http\Middleware;
use App\Models\UserAdmin;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
class AuthAdminJwt
{
/**
* @param Request $request
* @param Closure $next
* @return \Illuminate\Http\JsonResponse|mixed
*/
public function handle(Request $request, Closure $next)
{
//配置JWTAuth::parseToken()->authenticate()读取user_admin表,默认读取user表
Config::set('auth.providers.users.model', UserAdmin::class);
try {
if (!$user = JWTAuth::parseToken()->authenticate()) { //获取到用户数据,并赋值给$user
return response()->json([
'code' => 1,
'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参数',
]);
}
}
}
第三步:配置路由
第一种:配置路由中间件属性
(1):通过路由规则配:
在Http\Kernel.php里面:
protected $routeMiddleware = [
'jwt.admin.auth' => \App\Http\Middleware\AuthAdminJwt::class,
];
然后配置路由规则:
Route::get("/user/detail", [UserController::class, "detail"])->middleware('jwt.admin.auth');
运行这个路由,如果没有给token,就会报错。成功。
(2)还有一种是通过控制器配置中间件:
在Http\Kernel.php里面,这个和上面一样:
protected $routeMiddleware = [
'jwt.admin.auth' => \App\Http\Middleware\AuthAdminJwt::class,
];
接着在控制器里面的构造方法里面:
<?php
/**
* Created by PhpStorm.
* User: xyf
* Date: 2022/5/6
* Time: 13:34
*/
namespace App\Http\Admin\Account;
use App\Http\Admin\Controller;
use App\Http\Requests\AdminLoginRequest;
use App\Models\UserAdmin;
class LoginController extends Controller
{
public function __construct()
{
//除了login方法,其他需要验证token
$this->middleware('jwt.admin.auth', ['except' => ['login']]);
}
/**
* 登录
*
* @param AdminLoginRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function login(AdminLoginRequest $request)
{
$credentials = request(['mobile', 'password']);
if (!$token = auth("admin")->attempt($credentials)) {
return $this->fail("登录失败");
}
return $this->success([
'access_token' => $token,
'token_type' => 'Bearer',
'expires_in' => auth('admin')->factory()->getTTL()
]);
}
/**
* 退出登录
*
* @return \Illuminate\Http\JsonResponse
*/
public function logout()
{
auth("admin")->logout();
return $this->success();
}
public function test()
{
return $this->success();
}
}
第二种:配置路由中间件组属性
在Http\Kernel.php里面:
protected $middlewareGroups = [
'web' => [
//.......
],
'api' => [
//......
],
'admin'=>[
\App\Http\Middleware\Auth\AuthAdminJwt::class,
]
];
或则另一种写法:
protected $middlewareGroups = [
'web' => [
//.......
],
'api' => [
//......
],
'admin'=>[
/**
这种写法前提是在protected $routeMiddleware = [
'jwt.admin.auth' => \App\Http\Middleware\AuthAdminJwt::class,]配置了
**/
"jwt.admin.auth"
];
]
];
然后配置路由规则:
Route::group(['middleware' => 'admin'],function(){
Route::post("/account/test", [LoginController::class, "test"]);
Route::post("/account/logout", [LoginController::class, "logout"]);
});
或则另一种写法:
Route::middleware(['admin'])->group(function (){
Route::post("/account/test", [LoginController::class, "test"]);
Route::post("/account/logout", [LoginController::class, "logout"]);
});
这样你运行上面的路由就会验证token