用户权限控制 ----- Auth认证(lumen篇)
来源:互联网 发布:apache与nginx的进程 编辑:程序博客网 时间:2024/06/10 22:27
流程大览
在lumen中使用auth认证
- 注册AuthServiceProvider服务提供中,框架已经注册好了,只需要解开
bootstrap/app.php
中AuthServiceProvider
的调用取消代码注释; - 支持ORM,用于获取认证用户,解开
$app->withEloquent();
的调用注释,如果需要通过Auth::User
的方式获取认证用户,需要解开$app->withFacades()
的调用; - 支持路由中间件,把
bootstrap/app.php
里对$app->routeMiddleware()
的调用 「取消代码注释」,$app->routeMiddleware([
「取消代码注释;
'auth' => App\Http\Middleware\Authenticate::class,
]); - 还是在
bootstrap/app.php
添加自定义配置文件role.php
定义$app->configure('role');
,用于路由权限规则定义。
流程说明
登录流程:用户登录 —> 登录验证成功—>生成用户token并保存在数据库 ;
除登录外的其他访问:在AuthServiceProvider
服务提供中验证token的有效性与时效性,验证通过返回认证用户信息,在auth中间件中获取当前访问URI,通过当前认证用户的信息从数据库获取当前用户所拥有的权限,通过权限列表(具体的权限和路由具有对应关系)与当前路由验证用户是否拥有访问权限。
数据表设计
- 用户表:
Schema::create('staff_users', function (Blueprint $table) { $table->increments('id'); $table->string('name',30)->comment('用户名称'); $table->string('alias',30)->nullable()->comment('用户别名'); $table->char('pwd',32)->comment('密码'); $table->enum('status',[0,1])->default(1)->comment('状态 0 禁用 1 启用'); $table->string('phone',11)->comment('手机'); $table->json('extend')->nullable()->comment('用户扩展信息,如登录token等'); $table->softDeletes(); $table->timestamps(); $table->index('status'); });
- 权限表:
Schema::create('staff_roles', function (Blueprint $table) { $table->increments('id'); $table->string('rule_name',20)->comment('权限名称'); $table->string('rule',20)->comment('具体权限'); $table->enum('status',[1,0])->comment('状态 0 禁用 1,启用'); $table->softDeletes(); $table->timestamps(); $table->index('status'); $table->unique('rule'); });
*其中rule字段就是记录具体的访问路由,比如一个获取订单列表的URI是order/list
就记录成rule.list
‘;
- 权限小组表
Schema::create('staff_group', function (Blueprint $table) { $table->increments('id'); $table->string('name',30)->comment('组名'); $table->string('desc','200')->comment('简单描述'); $table->enum('status',[0,1])->defaule(1)->comment('状态,0 禁用 1 启用'); $table->softDeletes(); $table->timestamps(); });
该表用于权限分组
- 小组权限对应表
Schema::create('staff_group_rules', function (Blueprint $table) { $table->increments('id'); $table->integer('rule_id')->unsigned(); $table->integer('group_id')->unsigned(); $table->timestamps(); $table->foreign('rule_id')->references('id')->on('staff_roles')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('group_id')->references('id')->on('staff_group')->onDelete('cascade')->onUpdate('cascade'); });
该表用于记录规则与规则组对应关系
- 用户小组表
Schema::create('staff_users_group', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id')->unsigned(); $table->integer('group_id')->unsigned(); $table->timestamps(); $table->foreign('user_id')->references('id')->on('staff_users')->onDelete('cascade')->onUpdate('cascade'); $table->foreign('group_id')->references('id')->on('staff_group')->onDelete('cascade')->onUpdate('cascade'); });
该表用于记录用户所属权限小组
代码实现:
- 登录:
public function login(Request $request) { $account = $request->input('account', ''); $pwd = $request->input('password', ''); if (!$account || !$pwd) { return Code::_620(); } //注入服务类获取单个用户信息 $info = $this->accountService->getInfoByName($account); if (!$info || $info->password != Assistants::getPwd($pwd)) { //自定义的json返回方式 return Code::_620(); } //自定义的服务容器 $helper = app('helper'); //产生token的自定义函数 $pro = createToken($info->id); //将token按时间加密 $token = $helper->getToken($pro); /** 以下是其他业务,代码到这里登录流程就差不多了,产生了token,更新数据库的原token,如果没有存入token。 **/ $seller = $info->seller()->where('status', SellerAssistants::ACTIVE_STATUS)->get()->toArray(); if(!$seller){ return Code::_500('该账号已被停用'); } $auth = env('AUTH'); $seller = array_map(function ($item) use ($auth) { if ($item['is_master']) { $item['permissions'] = $auth; } return ['store_id' => $item['seller_id'], 'auth' => $item['permissions']]; }, $seller); $seller_ids = array_column($seller, 'store_id'); $store = $this->accountService->getStore($seller_ids); $tempSeller = []; foreach ($seller as $val) { $tempSeller[$val['store_id']] = $val; } $returnData = ['token' => $token, 'name' => $info->name, 'store' => []]; foreach ($store as $val) { if (isset($tempSeller[$val['id']])) { $temp = $tempSeller[$val['id']]; $temp['store_name'] = $val['name']; $returnData['store'][] = $temp; } } //更新token $extend = json_decode($info->extend, true); $extend['token'] = strtoupper($pro); if (count($store) == 1) { $extend['lastStore'] = $store[0]['id']; } $info->extend = json_encode($extend, true); if (!$info->save()) { return Code::_620(); } return Code::Y($returnData); } //以下为
- 生成时间加密的token:
//这里是对第一步的补充说明,分别是生产token,按时间加密,解密token的相关函数//生产tokenfunction createToken($uid = 0){ $time = uniqid($uid); $rand = random_int(0, 1000); return md5(md5($time) . md5($rand));}//时间加密function getToken($token='',$str=''){ if(!$token){ $token = strtoupper(env('ACCESS_KEY','MYNAMEDIAMONDS@A!KILL^&!MING@YIQ')); } $str = $str?$str:'MINGYI'; $l=strlen($str); $l=$l>8?8:$l; $len = 0 - $l; $time=substr(date('Ymd'),$len); $b = $time; while($time !==''){ $char = $time[0]; $token = substr_replace($token,$str[0],$char,0); $time =substr_replace($time,'',0,1); $str =substr_replace($str,'',0,1); } if(strlen($l)<2){ $l='A'.$l; } return strtoupper($l.$token.$b); } //解密获取原生token function getProToken($token=''){ if(!$token){ return $token; } $l = substr($token,0,2); if(intval($l) <1){ $l = substr($l,-1); } $len= 0 - $l; if($len >= 0){ return $token; } $token = substr($token,2); $time = substr($token,$len); $now = date('Ymd'); $pre = substr_replace($now,$time,$len,$l); $str=[]; while ($time !==''){ $index= strlen($time) - 1; $s = $time[$index]; array_unshift($str,$token[$s]); $token = substr_replace($token,'',$s,1); $time = substr_replace($time,'',$index,1); } $token =substr_replace($token,'',$len); return ['token'=>$token,'time'=>$pre,'str'=>join('',$str)]; }
- AuthServiceProvider服务提供者token验证
/** AuthServiceProvider服务提供者位置: app/Providers/AuthServiceProvider.php**///用户信息我是存在这个模型中的,默认是use的Useruse App\Models\Assistants;......... public function boot() { // Here you may define how you wish users to be authenticated for your Lumen // application. The callback which receives the incoming request instance // should return either a User instance or null. You're free to obtain // the User instance via an API token or any other method necessary. $this->app['auth']->viaRequest('api', function ($request) { if(env('AUTH_DEBUG',false)){ //调试模式不验证 return Assistants::first(); } //从消息头获取传入的token $token = $request->headers->get('token'); if(!$token){ die("token不能为空!"); } //解密原声token,获取token,时间,过期时间 $sign = app('helper')->getProToken($token); $date = date("Ymd"); $timeout = env('TOKEN_TIMEOUT',0); //验证token是否过期 if ((!$timeout || ($date - (int)$sign['time']) < $timeout) && $sign['token']) { //token验证通过返回当前认证用户 return Assistants::where('extend->token',$sign['token'])->first(); } return null; }); }
- auth中间件路由权限检测
/**auth中间件的位置:app/Http/Middleware/Authenticate.php**/ /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param string|null $guard * @return mixed */ public function handle($request, Closure $next, $guard = null) { if ($this->auth->guard($guard)->guest()) { return Code::_401(); }//获取认证用户信息$request->user() $userExtend = json_decode($request->user()->extend, true); if (!isset($userExtend['lastStore'])) { return Code::_401(); } /** 获取权限begin 以下代码根据设计的数据库,结合当前用户信息获取用户拥有的权限(或所在权限组拥有的权限,权限可以理解成拥有哪些路由) **/ $sellerUser = SellerAssistants::where([['seller_id', $userExtend['lastStore']], ['assistant_id', $request->user()->id]])->first(); if (!$sellerUser->is_master) { $permissions = explode(',', $sellerUser->permissions); $commonRole = config('role.common'); $role = config('role.auth'); $userRole = array_flip($permissions); $vaild = array_merge(array_flatten(array_intersect_key($role, $userRole)), $commonRole); //获取权限 end //获取当前URI $path = $request->path(); //获取以“/”开始后面的路由,例如:http://www.xxx.com/order/list 就获取order.list $method = str_replace('/', '.', substr($path, 0, strpos($path, '/'))); //判断当前处理过后的路由是否在所拥有的权限中 if (!in_array($method, $vaild)) { return Code::_402(); } } //验证通过 return $next($request); }
阅读全文
0 0
- 用户权限控制 ----- Auth认证(lumen篇)
- Lumen上使用Dingo/Api做API开发时用JWT-Auth做认证的实现
- Lumen上使用Dingo/Api做API开发时用JWT-Auth做认证的实现
- Lumen上使用Dingo/Api做API开发时用JWT-Auth做认证的实现
- lumen 用户认证
- Laravel 中用户认证(Auth)
- thinkphp Auth 权限认证
- MongoDB auth认证
- thinkphp auth认证表
- 腾讯auth认证
- django.contirb.auth-认证
- django.contirb.auth-认证
- TP3.2.3 Auth认证
- twemproxy auth认证时序
- Thinkphp5 Auth权限认证
- mongodb设置auth认证
- Auth类认证
- Thinkphp5 Auth权限认证
- Attempt to invoke virtual method 'void android.graphics.drawable.Drawable.setAlpha(int)' on a null o
- 网易2018校园招聘的部分编程题
- 利用Python做数据分析——numpy基础
- Linux环境下安装yafu
- Tomcat access log配置
- 用户权限控制 ----- Auth认证(lumen篇)
- python多线程编程
- Scala模式匹配
- PHPSTORM配置 PHP 单元测试
- hdu4112-规律&二进制- Break the Chocolate
- C
- Pan Download(百度网盘高速下载器)单文件版V1.4.3下载 | pandownload1.4.3
- 打劫房屋-LintCode
- < 笔记 > Python