laravel 用户认证,角色鉴权中间件
用户表
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`role_id` int(10) unsigned NOT NULL COMMENT '角色ID',
`username` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '用户名',
`password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密码',
PRIMARY KEY (`id`),
UNIQUE KEY `users_username_unique` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';
角色表
CREATE TABLE `user_roles` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`rules` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
权限规则表
CREATE TABLE `user_rules` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '规则',
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '菜单名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
新增认证,鉴权中间件 \app\Http\Middleware\Role.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class Role
{
/**
* 用户权限控制中间件
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
$noNeedRight = ['index', 'notify', 'sms', 'refundNotify', 'test', 'login', 'register','menu','shequ']; //无需登录鉴权的路由别名
$path = $request->path();
$pathArray = explode('/', $path);
switch (count($pathArray)) {
case 3:
//三级路由,取中间一级
$path = $pathArray[1];
break;
case 4:
//四级路由,取中间两级
$path = "$pathArray[1]/$pathArray[2]";
break;
default:
//默认三级路由,取中间一级
$path = $pathArray[1];
break;
}
if (in_array($path, $noNeedRight)) {
return $next($request);
}
//先做登录认证
if (!auth('api')->check()) {
return response()->json([
'code' => 401,
"msg" => '请登录后操作!',
"data" => null
]);
}
$rule_id = DB::table('user_rules')->where('name', $path)->value('id');
$role_id = auth('api')->user()->role_id;
$user_rules = DB::table('user_roles')->where('id', $role_id)->value('rules');
if ($user_rules === 0) {
//超级管理员 不鉴权
return $next($request);
}
if (is_null($rule_id) || is_null($role_id) || !in_array($rule_id, explode(',', $user_rules))) {
return response()->json([
'code' => 403,
"msg" => '你没有权限访问!',
"data" => null
]);
}
return $next($request);
}
}
声明鉴权中间件:
\app\Http\Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array<int, class-string|string>
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array<string, array<int, class-string|string>>
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\AcceptHeader::class
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array<string, class-string|string>
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'role' => \App\Http\Middleware\Role::class
];
}
控制器使用方法:
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function __construct()
{
$this->middleware('role');
}
public function index(Request $request)
{
return response()->json(auth('api')->user());
}
}