Commit bef6ec3a authored by 朱招明's avatar 朱招明

update

parent 29f8e5ab
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('user_login_logs', function (Blueprint $table) {
$table->id();
$table->integer('user_id')->index()->comment('用户ID');
$table->string('ip')->nullable()->comment('请求IP');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('user_login_logs');
}
};
<?php
namespace Modules\Admin\Entities;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class AdminOperationLog extends Model
{
protected $fillable = ['user_id', 'path', 'method', 'ip', 'input'];
public static $methodColors = [
'GET' => 'green',
'POST' => 'yellow',
'PUT' => 'blue',
'DELETE' => 'red',
];
public static $methods = [
'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH',
'LINK', 'UNLINK', 'COPY', 'HEAD', 'PURGE',
];
/**
* Create a new Eloquent model instance.
*
* @param array $attributes
*/
public function __construct(array $attributes = [])
{
$connection = config('admin.database.connection') ?: config('database.default');
$this->setConnection($connection);
$this->setTable(config('admin.database.operation_log_table'));
parent::__construct($attributes);
}
/**
* Log belongs to users.
*
* @return BelongsTo
*/
public function user(): BelongsTo
{
return $this->belongsTo(config('admin.database.users_model'));
}
protected function serializeDate(\DateTimeInterface $date)
{
return $date->format(Carbon::DEFAULT_TO_STRING_FORMAT);
}
}
<?php
/**
* @desc
* @author [ZZM]
* @since 2023/10/30
* @copyright
*/
namespace Modules\Admin\Entities;
use Illuminate\Database\Eloquent\Model;
class UserLoginLog extends Model
{
protected $fillable = ['user_id', 'ip'];
}
\ No newline at end of file
<?php
namespace Modules\Admin\Events;
use Illuminate\Queue\SerializesModels;
class UserLoginEvents
{
use SerializesModels;
public $user;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($user)
{
$this->user = $user;
}
/**
* Get the channels the event should be broadcast on.
*
* @return array
*/
public function broadcastOn()
{
return [];
}
}
...@@ -10,6 +10,7 @@ use Illuminate\Support\Facades\Cache; ...@@ -10,6 +10,7 @@ use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Modules\Admin\Entities\AdminMenu; use Modules\Admin\Entities\AdminMenu;
use Modules\Admin\Entities\AdminUser; use Modules\Admin\Entities\AdminUser;
use Modules\Admin\Events\UserLoginEvents;
use Modules\Admin\Http\Transformers\AccessTokenTransformer; use Modules\Admin\Http\Transformers\AccessTokenTransformer;
use Modules\Admin\Http\Transformers\AdminUserTransformer; use Modules\Admin\Http\Transformers\AdminUserTransformer;
use Modules\Admin\Http\Transformers\BaseTransformer; use Modules\Admin\Http\Transformers\BaseTransformer;
...@@ -72,6 +73,8 @@ class AuthController extends BaseController ...@@ -72,6 +73,8 @@ class AuthController extends BaseController
throw new \Exception("用户名或密码错误"); throw new \Exception("用户名或密码错误");
} }
event(new UserLoginEvents($user));
return $this->response->item($user, new AccessTokenTransformer())->setStatusCode(201); return $this->response->item($user, new AccessTokenTransformer())->setStatusCode(201);
} }
...@@ -158,6 +161,7 @@ class AuthController extends BaseController ...@@ -158,6 +161,7 @@ class AuthController extends BaseController
$role = $user->roles()->first(); $role = $user->roles()->first();
$data = [ $data = [
'user_info' => Helper::mapAttr($user,['id', 'username', 'avatar', 'avatar_full_url', 'name', 'created_at', 'updated_at']),
"menus" => Helper::getRoleMenu($role,true), "menus" => Helper::getRoleMenu($role,true),
"apis" => Helper::getRoleApi($role,true), "apis" => Helper::getRoleApi($role,true),
]; ];
......
<?php
namespace Modules\Admin\Http\Middleware;
use Modules\Admin\Entities\AdminOperationLog as OperationLogModel;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class LogOperation
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle(Request $request, \Closure $next)
{
if ($this->shouldLogOperation($request)) {
$user = auth()->user();
$log = [
'user_id' => $user->id,
'path' => substr($request->path(), 0, 255),
'method' => $request->method(),
'ip' => $request->getClientIp(),
'input' => json_encode($request->input()),
];
try {
OperationLogModel::create($log);
} catch (\Exception $exception) {
logger($exception->getMessage());
}
}
return $next($request);
}
/**
* @param Request $request
*
* @return bool
*/
protected function shouldLogOperation(Request $request)
{
return !$this->inExceptArray($request)
&& $this->inAllowedMethods($request->method())
&& auth()->user();
}
/**
* Whether requests using this method are allowed to be logged.
*
* @param string $method
*
* @return bool
*/
protected function inAllowedMethods($method)
{
$allowedMethods = collect(['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH'])->filter();
if ($allowedMethods->isEmpty()) {
return true;
}
return $allowedMethods->map(function ($method) {
return strtoupper($method);
})->contains($method);
}
/**
* Determine if the request has a URI that should pass through CSRF verification.
*
* @param \Illuminate\Http\Request $request
*
* @return bool
*/
protected function inExceptArray($request)
{
$excepts = [
'api/admin/auth/logs*',
];
foreach ($excepts as $except) {
if ($except !== '/') {
$except = trim($except, '/');
}
$methods = [];
if (Str::contains($except, ':')) {
[$methods, $except] = explode(':', $except);
$methods = explode(',', $methods);
}
$methods = array_map('strtoupper', $methods);
if ($request->is($except) &&
(empty($methods) || in_array($request->method(), $methods))) {
return true;
}
}
return false;
}
}
...@@ -7,7 +7,7 @@ use Illuminate\Http\Request; ...@@ -7,7 +7,7 @@ use Illuminate\Http\Request;
use Dingo\Api\Facade\Route; use Dingo\Api\Facade\Route;
use Modules\Admin\Http\Utils\Helper; use Modules\Admin\Http\Utils\Helper;
class RoleMenu class Permission
{ {
/** /**
* Handle an incoming request. * Handle an incoming request.
...@@ -25,9 +25,7 @@ class RoleMenu ...@@ -25,9 +25,7 @@ class RoleMenu
$apis = array_filter(array_column(Helper::getAllApi(),'api')); $apis = array_filter(array_column(Helper::getAllApi(),'api'));
$route = str_replace(".", "/", Route::currentRouteName()); $route = str_replace(".", "/", Route::currentRouteName());
logger($route);
logger($role_apis);
logger($apis);
#验证菜单权限 #验证菜单权限
if( if(
!Helper::isAdministrator($role->id) !Helper::isAdministrator($role->id)
......
...@@ -8,9 +8,9 @@ class MenuRequest extends BaseRequest ...@@ -8,9 +8,9 @@ class MenuRequest extends BaseRequest
{ {
if(empty($this->parent_id)){ if(empty($this->parent_id)){
$this['parent_id'] = 0; $this['parent_id'] = 0;
$parent_id_rule = []; $parent_id_rule = ['integer'];
}else{ }else{
$parent_id_rule = ['exists:admin_menus,id']; $parent_id_rule = ['integer','exists:admin_menus,id'];
} }
return [ return [
...@@ -24,7 +24,7 @@ class MenuRequest extends BaseRequest ...@@ -24,7 +24,7 @@ class MenuRequest extends BaseRequest
public function putRules() public function putRules()
{ {
if(empty($this->parent_id)){ if(empty($this->parent_id)){
$this->parent_id = 0; $this['parent_id'] = 0;
$parent_id_rule = ['integer']; $parent_id_rule = ['integer'];
}else{ }else{
$parent_id_rule = ['integer','exists:admin_menus,id']; $parent_id_rule = ['integer','exists:admin_menus,id'];
......
<?php
namespace Modules\Admin\Listeners;
use Modules\Admin\Entities\UserLoginLog as UserLoginLogModel;
use Modules\Admin\Events\UserLoginEvents;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class UserLoginListeners
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param UserLoginEvents $event
*
* @return void
*/
public function handle(UserLoginEvents $event)
{
$user = $event->user;
$log = [
'user_id' => $user->id,
'ip' => request()->getClientIp(),
];
try {
UserLoginLogModel::create($log);
} catch (\Exception $exception) {
logger($exception->getMessage());
}
}
}
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace Modules\Admin\Providers; namespace Modules\Admin\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Modules\Admin\Http\Service\AuthService; use Modules\Admin\Http\Service\AuthService;
use Modules\Admin\Http\Utils\AuthInterface; use Modules\Admin\Http\Utils\AuthInterface;
...@@ -31,6 +32,9 @@ class AdminServiceProvider extends ServiceProvider ...@@ -31,6 +32,9 @@ class AdminServiceProvider extends ServiceProvider
$this->registerViews(); $this->registerViews();
$this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations')); $this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations'));
$this->registerAntOAInterfaces(); $this->registerAntOAInterfaces();
Event::listen('Modules\Admin\Events\UserLoginEvents', 'Modules\Admin\Listeners\UserLoginListeners');
} }
/** /**
......
...@@ -34,7 +34,7 @@ $api->version('v1', [ ...@@ -34,7 +34,7 @@ $api->version('v1', [
#上传文件 #上传文件
$api->post('files', 'FilesController@store'); $api->post('files', 'FilesController@store');
$api->group(['middleware' => 'role_menu'], function ($api){ $api->group(['middleware' => ['admin.permission','admin.log_operation']], function ($api){
#菜单 #菜单
\Modules\Admin\Http\Utils\RouteRegister::registerApi($api,'menu','MenuController'); \Modules\Admin\Http\Utils\RouteRegister::registerApi($api,'menu','MenuController');
...@@ -43,8 +43,6 @@ $api->version('v1', [ ...@@ -43,8 +43,6 @@ $api->version('v1', [
#角色 #角色
\Modules\Admin\Http\Utils\RouteRegister::registerApi($api,'role','RoleController'); \Modules\Admin\Http\Utils\RouteRegister::registerApi($api,'role','RoleController');
#角色权限
$api->put('role/{id}/set_menu', 'RoleController@setRoleMenu')->name("role.set_menu");;
}); });
}); });
......
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
<p align="center">
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
</p>
## About Laravel
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
- [Simple, fast routing engine](https://laravel.com/docs/routing).
- [Powerful dependency injection container](https://laravel.com/docs/container).
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
Laravel is accessible, powerful, and provides tools required for large, robust applications.
## Learning Laravel
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
## Laravel Sponsors
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
### Premium Partners
- **[Vehikl](https://vehikl.com/)**
- **[Tighten Co.](https://tighten.co)**
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
- **[64 Robots](https://64robots.com)**
- **[Cubet Techno Labs](https://cubettech.com)**
- **[Cyber-Duck](https://cyber-duck.co.uk)**
- **[Many](https://www.many.co.uk)**
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
- **[DevSquad](https://devsquad.com)**
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
- **[OP.GG](https://op.gg)**
- **[WebReinvent](https://webreinvent.com/?utm_source=laravel&utm_medium=github&utm_campaign=patreon-sponsors)**
- **[Lendio](https://lendio.com)**
## Contributing
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
## Code of Conduct
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
## Security Vulnerabilities
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
## License
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
namespace App\Http; namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel; use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Modules\Admin\Http\Middleware\RoleMenu;
class Kernel extends HttpKernel class Kernel extends HttpKernel
{ {
...@@ -65,6 +64,7 @@ class Kernel extends HttpKernel ...@@ -65,6 +64,7 @@ class Kernel extends HttpKernel
'signed' => \App\Http\Middleware\ValidateSignature::class, 'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'role_menu' => RoleMenu::class, 'admin.permission' => \Modules\Admin\Http\Middleware\Permission::class,
'admin.log_operation' => \Modules\Admin\Http\Middleware\LogOperation::class,
]; ];
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment