这次开发会员列表的时候遇到的问题首先有100个用户状态码为以下
正常:1 / 冻结:2 / 删除:0
总数:100名 / 正常:34名 / 冻结:30名 / 删除:36名
-
这里是用户表格
// router
Route::get('member/{state?}','MemberController@browse')
->where(['state' => 'total|block|delete']);
// controller
// $state 默认是 normal
switch($state){
case 'block':$where[] = ['state','=',2];break;
case 'normal':$where[] = ['state','=',1];break;
case 'delete':$where[] = ['state','=',0];break;
}
$members = Member::where($where)->paginate(30);
但假如我要计数的话,必须得这么做么?
$count = [
'total' => Member::count(),
'block' => Member::where('state',2)->count(),
'normal' => Member::where('state',1)->count(),
'delete' => Member::where('state',0)->count(),
];
// controller
// $state 默认是 normal
switch($state){
case 'block':$where[] = ['state','=',2];break;
case 'normal':$where[] = ['state','=',1];break;
case 'delete':$where[] = ['state','=',0];break;
}
$members = Member::where($where)->paginate(30);
return view('xxx',compact('count','members'));
还是有别的方法啊?我觉得这也太原始了。我写那么多Member::where是否对数据库有负载?DEBUG里显示是这样
select * from `admins` where `id` = '1' limit 1
select count(*) as aggregate from `members`
select count(*) as aggregate from `members` where `state` = '1'
select count(*) as aggregate from `members` where `state` = '2'
select count(*) as aggregate from `members` where `state` = '0'
select count(*) as aggregate from `members` where (`state` = '0')
select * from `members` where (`state` = '0') order by `id` desc limit 30 offset 0
觉得用户列表有太多数据库请求,
这个有没有优化的方法?还是不管这些一直写下去?
这次开发会员列表的时候遇到的问题首先有100个用户状态码为以下
正常:1
冻结:2
删除:0
-
总数:100名 / 正常:34名 / 冻结:30名 / 删除:36名
-
这里是用户表格
// router
Route::get('member/{state?}','MemberController@browse')
->where(['state' => 'total|block|delete']);
// controller
// $state 默认是 normal
switch($state){
case 'block':$where[] = ['state','=',2];break;
case 'normal':$where[] = ['state','=',1];break;
case 'delete':$where[] = ['state','=',0];break;
}
$members = Member::where($where)->paginate(30);
但假如我要计数的话,必须得这么做么?
$count = [
'total' => Member::count(),
'block' => Member::where('state',2)->count(),
'normal' => Member::where('state',1)->count(),
'delete' => Member::where('state',0)->count(),
];
// controller
// $state 默认是 normal
switch($state){
case 'block':$where[] = ['state','=',2];break;
case 'normal':$where[] = ['state','=',1];break;
case 'delete':$where[] = ['state','=',0];break;
}
$members = Member::where($where)->paginate(30);
return view('xxx',compact('count','members'));
还是有别的方法啊?我觉得这也太原始了。我写那么多Member::where是否对数据库有负载?DEBUG里显示是这样
select * from `admins` where `id` = '1' limit 1
select count(*) as aggregate from `members`
select count(*) as aggregate from `members` where `state` = '1'
select count(*) as aggregate from `members` where `state` = '2'
select count(*) as aggregate from `members` where `state` = '0'
select count(*) as aggregate from `members` where (`state` = '0')
select * from `members` where (`state` = '0') order by `id` desc limit 30 offset 0
觉得用户列表有太多数据库请求,
这个有没有优化的方法?还是不管这些一直写下去?
最近玩下lumen 只是简单测试,
但发现单页登录的时候获取的TOKEN不知道存哪。
存在cookie吧~关闭浏览器时可能还存在着,
设置有效期吧~觉得对长时间泡的网站的人来说是个麻烦事。
虽然没有试过 sessionstorage ,但网上一大堆说新标签里用不了。
懒人一枚,所以没有试。
1.用户进入首页时先判断有没有token
2.有【直接用token跟DB里的token核对,不符合就跳登录页面】没有【跳转到登录页面】
3.登录后给用户一个新token。
4.这里就懵了,PHP和 JS都能拿到 token【刚登录完的时候】
然后不知道放哪里了。
想要session一样的 关闭浏览器就回结束会话的存储机构,
不知道哪位大神指导下~~
* 我只是想用lumen自带的功能里实现,不要太复杂
只是简单测试所以没想用依赖啥的
我在首页设置了访问授权
public function index()
{
$role = Role::find(1);
// admin 已经登录了,Auth::guard('admin')->user(); 能获取到
$chk = Gate::denies('showA',$role);
return $chk ? '没有授权' : '已授权';
}
问题是 AuthServiceProvider 这里我改怎么写呢?
因为我没用官方提供的User模型,自己新建了一个Admin模型
官方文档也都是 User模型来说明,不知道怎么弄。
我的Admin 在 AppHttpModelsAdmin::class
// 这里是看着视频添加的,不知道什么意思
// $user是什么时候获取的 找了半天源码还是看不明白。
public function boot()
{
$this->registerPolicies();
Gate::define('showA',function($user,$role){
return !! $user->role_id === $role->id;
});
}
找到问题了,因为config/auth.php里的 default = web
指定用户的话可以通过。哎
$this->authorizeForUser($user,'showA',$role);
请问有没有在boot里面指定guard方法吗?
我看过《Laravel 实现用户权限管理》系列视频
我想呈现的效果有些不一样,能否给个思路。
用户表是一样的,只是多了一个 role_id 字段。
每个用户只能获取一个角色,这里只存储角色表的id
角色表,假如添加角色的时候表单如下:
【角色名】= 只是显示的,用在添加用户的时候 角色select里显示的文字
....
....
....
【权限】
- [x] 文章管理
- [x] 文章列表 [x] 添加文章 [x] 编辑文章 [x] 删除文章
- [x] 分类管理
- [x] 分类列表 [ ] 添加分类 [ ] 编辑分类 [ ] 删除分类
【确认】【返回】
这里的权限是由导航菜单提供的
菜单表是跟其他普通导航菜单一样,只是多了两个字段。
一个是权限key【类似视频里的 edit_form】
还有一个是是否隐藏字段,隐藏的话不会在导航里显示
如:添加文章,编辑文章,删除文章 这些菜单上设置隐藏
因为用菜单表的数据来显示sidebar菜单
foreach($menus as $menu)
{
if($menu['is_hidden'] !== 1)
{
// 显示sidebar菜单列表
}
}
我这样的方法,要实现权限的话该怎么弄呢?
谢谢你的答复,这个也是没法获取新的token值。
该问题已解决了,没必要自动刷新token,只要发送POST前刷新一次就行Route
Route::get('token',function(){
return csrf_token();
});
Login Vue
Vue.http.get('/token').then((response) => {
window.Laravel.csrfToken = response.body;
Vue.http.post(...);// ajax提交
});
大概是这个逻辑,还有更好的解决方案的话,教导我下下 233333
我用L5 和 Vue2 做了一个登陆页面。
都可以正常操作,但发现过一段时间再提交会出现token错误。
因为vue-router 我没用 history来访问。
所以网站的token一直是一个值。
刚开始我是在JS里直接定义
window.Laravel = {
csrfToken:" csrf_token() "
};
我想因为地址是 xxx.com/#/admin/login 这个形式,所以没法刷新token的。
(个人理解的)
但是总不能每几秒ajax一个token吧,觉得也不合适。
是否有更好更方便的解决方式呢?
我的模板文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>...</title>
<link rel="stylesheet" href=" asset('sources/normalize.min.css') ">
<link rel="stylesheet" href=" asset('sources/admin/admin.css') ">
</head>
<body>
<div id="Ant"></div>
</body>
<script>
window.Laravel = {
csrfToken:" csrf_token() "
};
window.User = {!! auth()->guard('admin')->user() ?: 'null' !!};
</script>
<script src=" asset('sources/admin/admin.js') "></script>
</html>
IndexController@index
$data = ['username' => 'admin','password' => '123456'];
if(Auth::guard('admin')->attempt($data))
{
return dd(Auth::guard('admin')->user());
}
IndexController@other
return dd(Auth::guard('admin')->user());
配置路由
Route::get('/','IndexController@index');
Route::get('/other','IndexController@other');
结果 第一个是可以取到数据的
但第二个就不会取到数据是为什么呢?
官方文档说
attempt
方法会接受一个数组来作为第一个参数
这个数组的值可用来寻找数据库里的用户数据
如果两个值一样的话就会开启一个通过认证的 session 给用户
但我测试user()
函数获取不了数据,是什么问题呢?
不好意思,刚才解决了问题,还是复制了下。
手动认证实在搞不懂。
为了怕别的同学也会掉坑,分享下。
1.登陆控制器部分
namespace App\Http\Controllers\Admin;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends BeforeController
{// 这里的Before别管 是自己添加的 公共控制器,暂时是个空的,是用 ThinkPHP 的习惯
use AuthenticatesUsers;
protected $redirectTo = 'admin';// 登陆后跳转
public function login()
{
return view('admin.login');
}
protected function guard()
{
return auth()->guard('admin');// 使用新添加的Guard
}
public function username()
{
return 'username';// 检测的用户名字段,数据库里用户名字段为uid 那么这里改下uid就行
}
}
2.Kernel里 添加
'auth.admin' => \App\Http\Middleware\AuthAdmin::class,
3.添加 Middleware
namespace App\Http\Middleware;
use Closure;
class AuthAdmin
{
public function handle($request, Closure $next)
{
if (auth()->guard('admin')->guest()) {// 刚才添加的Guard的名字
return redirect()->guest('admin/login');// 没有登陆直接跳转登陆页面
}
return $next($request);
}
}
4.路由添加
Route::get('admin/login','Admin\LoginController@show');
Route::post('admin/login','Admin\LoginController@login');
Route::group(['prefix' => 'admin','middleware' => 'auth.admin'],function(){
Route::get('/',function(){
$aa = \Illuminate\Support\Facades\Auth::guard('admin')->user();
return dd($aa);
});
});
忘了写Guard部分了,下面是Guard部分
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [// 新添加
'driver' => 'session',
'provider' => 'admins',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [// 新添加
'driver' => 'eloquent',
'model' => App\Http\Models\Admins::class,
],
],