Rails win7用户权限控制制问题,如何优雅的实现

关于 devise,用户分类权限的问题 · Ruby China
我用了devise这个gem,来快速完成用户模块的搭建。但是遇到了问题,不知到怎样去给用户不同的权限(或者让用户具有不同的类型),请大家帮帮忙
,项目的内容如下:
项目背景:
期末大作业,网上购物系统shoppingmall
系统角色:
1.系统管理员(MallManager)
2.店铺管理员(StoreManager)
3.普通用户
1.系统管理员
审批用户的开店申请
强制关闭店铺
2.店铺管理员
商品(Item)的增删改查
3.普通用户
devise不是干这活儿的 它只管登录注册
试试 cancan /rolify
不用rolify的原因在 #32 说明了,因为本人不太常用
那devise能和cancan 一块用吗
把它clone 下来
简单的权限的话,只需要加一个不用的model就可以了,比如只有admin和user,在只有admin可以访问的时候增加befor_filter就可以了,
如果设计复杂的权限,那就cancan吧
如果是3种权限呢?
那就多几个 if else
我一般是用几个表
1、roles,用户只有一个角色,users包含roler_id。如果是多个角色就加中间表roles_users
2、operates,权限表,里面会描述controller和action的信息
3、menus,菜单,依赖哪些operates
给角色分配权限,多少个角色都可以。给用户分配角色,用户就有角色的权限了。早期我的项目里还实现过roles有权限和users有权限,最后取并集,那更复杂。
3个model,针对不同的model使用不同的before_filter,最简单的做法。
如果复杂的情况简易用cancan
另外,拒绝使用if else,太丑了,
谢谢你,你给我的这个项目是同时整合了 devise, cancan, rolify 这三个gem.怎样去理清出中间的关系,用到我的项目中呢?
其实就是普通用户(User),管理账户(admin),假设admin中有一个field区分是其level,
然后在controller中使用
before_filter :authenticate_user
before_filter :mall_scope, only: [:index]
before_filter :store_scope, only: [:show]
def mall_scope
current_user.mall? ...blablabla
def store_scope
current_user.store? ...blablabla
在你的controller中,永远保持自己的action只有基本的CRUD标准action,尽量不增加其他action
我是照着它一点点搬过来,需要什么拿什么,就熟悉它的细节了。
cancan和rails 4的strong_parameter有兼容问题,而且确实已经很久没有维护了(master上次改动是9个月前,2.0被坑掉了),所以不推荐用cancan了
你的需求还算简单,可以用before_action来做访问控制。用户模型存角色
我的user这个Modle是用devise生成的,我可以随便改user的表结构,增加字段吗?
你觉得用多态取代表达式就没有 if else 了?
when Admin
降低代码复杂度,简单易懂,每次重构的目标都是让代码看起来更舒服。取决于个人喜好,另外,也不喜欢code climate分值太低
恩,谢了哈
恩,谢谢了。我试着写写
别整那么多,会晕的, 看来我误人子弟了。
简单的需求就自己去完成,复杂的用下cancan吧。
使用gem,得到的教训是学习成本高很多,定制起来还会很麻烦。
不过还是谢谢你
cancan 处理的也是简单问题,复杂问题还是要自己设计实现。
可以做成接口
class Admin & User
ROLES = User::ROLES + [:create_group, :update_group]
def can?(operation)
ROLES.include? operation
a_guest.can? create_group # =& false
an_admin.can? :create_group # =& true
通过STI来做是个好主意,可以避免if..elsif..else
用的时候不也是
if a_guest.can? create_group
哈 对对...
不过我习惯是
return redirect_to '403' unless a_guest.can? :create_group
这样能把结构弄扁
所以我的意思是,多几个权限就多几个 if else,无论这个 if else 是用语句形式,还是多态形式,还是 before_filter 形式,最终都取决于自己怎么设计自己的系统,而不是觉得这有点复杂不如找个 gem 吧,这不省多少事。
嗯,言之有理,刚才似乎理解错了
不过无论咋样,rails4时代,还没有一个靠谱的访问控制gem。。。
如果网站注册功能呢?是不是交给devise 就好了呢! 有没有比较好的权限的例子给一个看看呀~!
一直觉得rolify 做权限管理足够了,求教这玩意有什么弊病或者无法做到的导致 rolify
如果你的注册流程比较常规,devise可以
否则我建议用omniauth-identity或者自己写
比如knewone正在做的新流程,用户通过oauth注册可以不输入邮箱、没有密码,注册登录通过ajax,注册只需要输入密码无需确认密码等等,其实做完下来等于重新实现了devise控制器的部分,对model也有很大的hack,于是就很痛苦...devise的代码,一些部分还是不太容易理解的
恩,研究下看看啦。谢谢
我否定的原因是
一下给了LZ太多的选择,会耗费的精力,而我经常用cancan,比较熟,自然...
rolify的权限控制颗粒度很细,不像cancan样硬编码到文件中.挺好的
后方可回复, 如果你还没有账号请点击这里 。
共收到 32 条回复如何“优雅”管理iOS系统权限 - 简书
如何“优雅”管理iOS系统权限
在iOS开发中,难免会和各种系统权限打交道,比如相机、麦克风、相册、地理位置、日历、提醒事项(Reminder)以及联系人权限等等。基于iOS的特性,每一项权限只有在征得用户同意后,app才能使用相应的功能。这给了用户充分的自主权,也是iOS系统的一大优势。然而每一个权限往往对应于不同的系统library,程序员需要处理各个类库各种不同的API。如果不精心管理,权限获取的代码会分散在各个业务模块,调试起来会非常麻烦,而且iOS每次升级,都会对权限系统做调整,API接口也会有变化,非常不好维护。
例如,权限获取一般是下面这个样子:
//获取地理位置
/*判断用户是否已经同意地理位置权限,否则获取权限*/
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate =
[self.locationManager requestAlwaysAuthorization];
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
//获取用户日历
/*判断用户是否已经同意日历权限,否则获取权限*/
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:type];
self.eventStore = [[EKEventStore alloc] init];
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError * _Nullable error) {
这样的代码会干扰正常业务代码,而且分散在各个类,不容易维护。如果能有一个类,能统一管理各类权限,是不是会方便很多,而且维护成本也会降低不少?基于这样的构想,本人实现了一个权限管理的类,用户同意管理iOS的权限。支持相机、麦克风、相册、地理位置、日历、提醒事项(Reminder)以及联系人权限获取。
LFPermissionMgr.h
@interface LFPermissionMgr : NSObject
+ (LFPermissionMgr *)sharedI
- (void)accessCamera:(void (^)(BOOL granted))
- (void)accessMic:(void (^)(BOOL granted))
- (void)accessPhoto:(void (^)(BOOL granted))
- (void)accessLocation:(LocationAuthorizedType)authorizedType handler:(LocationHandler)
- (void)accessEvent:(EventAuthorizedType)eventType handler:(void (^)(BOOL granted))
- (void)accessContacts:(void (^)(BOOL granted))
使用方法:(支持iOS8+):
获取麦克风:
[[LFPermissionMgr sharedInstance] accessMic:^(BOOL granted) {
if (granted) {
NSLog(@"mic access granted");
NSLog(@"mic access not granted");
[[LFPermissionMgr sharedInstance] accessCamera:^(BOOL granted) {
if (granted) {
NSLog(@"camera access granted");
NSLog(@"camera access not granted");
[[LFPermissionMgr sharedInstance] accessPhoto:^(BOOL granted) {
if (granted) {
NSLog(@"photo access granted");
NSLog(@"photo access not granted");
获取地理位置
[[LFPermissionMgr sharedInstance] accessLocation:LocationAuthorizedAlways handler:^(BOOL granted, CLLocation *location) {
if (granted) {
NSLog(@"location access granted:[%f,%f]", location.coordinate.latitude, location.coordinate.longitude);
[[LFPermissionMgr sharedInstance] accessEvent:EventAuthorizedCalendar handler:^(BOOL granted) {
if (granted) {
NSLog(@"calendar access granted");
NSLog(@"calendar access not granted");
获取Reminder
[[LFPermissionMgr sharedInstance] accessEvent:EventAuthorizedReminder handler:^(BOOL granted) {
if (granted) {
NSLog(@"reminder access granted");
NSLog(@"reminder access not granted");
获取联系人
[[LFPermissionMgr sharedInstance] accessContacts:^(BOOL granted) {
if (granted) {
NSLog(@"contacts access granted");
NSLog(@"contacts access not granted");
用到的组件1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SDWebImage多个缩略图缓存组件 UICKeyChainStore存放用户账号密码组件 Reachability监测网络状态 DateTools友好...
发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注
09:45字数 61697阅读 3316评论 2喜欢 85 用到的组件 1、通过CocoaPods安装 项目名称 项目信息 AFNetworking 网络请求组件 FM...
下边都学会就大神了: 声明:都是网上搜集的,能标明出处的都标了.别只搜集而不看,与君共勉.. 先看完整项目完整App@HackerNews-React-Native用 React Native 完成的 HackerNews 客户端。WeChat实现类似微信朋友圈或者QQ空间...
Swift版本点击这里欢迎加入QQ群交流:
最新更新日期:17-11-01 About A curated list of iOS objective-C ecosystem. How to Use Simply presscommand+F+&xxx...
用到的组件1、通过CocoaPods安装项目名称项目信息AFNetworking网络请求组件FMDB本地数据库组件SDWebImage多个缩略图缓存组件UICKeyChainStore存放用户账号密码组件Reachability监测网络状态DateTools友好化时间MBP...
世界上有那么一种亲人,不问及儿女的心事,不谈及儿女的未来,更不会有一句温馨的祝福或是关心的话语,是我的爸爸,很平凡的生意人,仅此而已。- 记得妈妈说过爸爸不爱家,因为爸爸每晚都早出晚归,与我们相处的时间少之又少。爸爸不关心我们的学业与人品,可能是爸爸打心底就知道,我们能够自...
我的老家在江西省高安市,一个不大的小县城,也是初中高中读书上学的一个地方。 一个人在外面呆久了,对家的情感有点复杂,男孩子总归不怎么恋家,刚好自己也是一个情感内敛的人。 有次跟玩的比较好的同事聊天,国庆要不要回去呢?她的回答很简单,想回就回。对,想着刚好今年中秋节跟国庆节在...
1.懒加载基本懒加载——也称为延迟加载,即在需要的时候才加载(效率低,占用内存小)。所谓懒加载,写的是其get方法。注意:如果是懒加载的话则一定要注意先判断是否已经有了,如果没有那么再去进行实例化。2.使用懒加载的好处:(1)不必将创建对象的代码全部写在viewDidLoa...
在光中,我们看到了各种各样的色彩。色是光带来的,有光便有色。色彩不同,会影响到人们的情绪。
光给我们的不全是喜悦和欢乐,还有哀婉和忧愁。当光明给我们热情、温暖和希望时,我们应该懂得感恩,感谢光明馈赠;当光明给我们忧郁...
开放了好友,又怎样呢。该说的都说过了,不能说的,要时刻提醒自己,管住嘴,管住手。还有时时提醒自己不要生出妄念。而这样,在彼此的朋友圈里对望,尴尬得心慌。却又能见到你跟别人“打情骂俏”。我不想受这份罪。没有更多推荐了,
不良信息举报
举报内容:
在Rails中用CanCan进行权限控制
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!macOS High Sierra 版本 10.13.1
ruby 2.4.1p111
Rails 5.1.4
编辑软件:Atom(你可以选择其它软件,例如:Sublime Text、Ruby Mine 等等,我这里就使用 Atom )
DB Browser for SQLit3 (数据库读取软件)
注意:本次是从 0 开始做这个小练习,适合小白学习使用,大侠做.爱.做的事去吧,安装ruby和rails的方法这里就不写了,小白可以去&查阅。
xxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxooxxoo
&Devise是Ruby On Rails的一个三方权限认证组件,通过它你可以无需编码快速生成一个带有登陆、注册、权限认证和重置密码的用户认证模块。
&在Devise的基础上,另外增加一些功能实现多角色权限管理,当然还可以使用Cancancan Gem,但这里并不介绍Cancancan,因为我还没弄懂(T_T!)。
&操作流程:
1、打开终端(Terminal),进到你的工作目录,例如我的是workspace下,运行以下新建rails项目代码:
rails new project
注:以上这个代码是新建一个rails项目,名字为project。
2、进入project
cd project  
注:以上这个代码是进入project项目文件夹中,进入后会发现里面有很多文件了,这是rails为项目自动生成的,查看方法可以在终端用ls命令。
3、打开编辑软件Atom,点击 File-&Open-&Users-&mac-&workspace-&project (这个是我当前的工作目录,你的可能不一样),打开后如下图:
4、在Atom左边目录中找到Gemfile,进入,添加以下代码(如图):
gem 'devise'
注:以上这个代码是添加devise gem,如果不明白gem是什么这意思,可以点&&查看。
保存Gemfile文件。
5、打开终端(Terminal),在project的目录下输入下面代码:
bundle install
&注:以上这个代码是安装devise gem组件,这里的install可以省略不输入,输完后回车,刷刷刷等一会就安装好了。
6、继续在终端(Terminal)下输入以下代码:
rails g devise:install
注:以上这个代码是「产生devise设定档」(这翻译是那里抄的),按回车后你会发现以下内容:
按照上图,我们要做以下几个操作:
a、打开config/environments/development.rb 文件,在里面输入
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
注:以上这个代码是邮件功能的设置
b、打开&config/routes.rb,在里面输入
root to: "home#index"
注:以上这个代码是设置http://localhost:3000的访问路由,这里还没有创建这个home目录和index文件,下面再说。
c、打开app/views/layouts/application.html.erb 文件,加入以下代码:
&p class="notice"&&%= notice %&&/p&
&p class="alert"&&%= alert %&&/p&
注:以上这个代码是显示flash信息
d、在终端输入以下代码:
rails g devise:views
注:以上这个代码是产生html模板,包含有注册、登录、忘记密码、Email等页面,并放在app/views/devise目录下。
e、现在添加一个提前routes.rb里提到的home目录和index文件,在终端执行以下代码:
rails g controller home index
注:以上这个代码是产生了home controller index,意思就是我们设置的首页。另外我们到回routes.rb文件里(config/routes.rb),把 get 'home/index' 删除掉,只用 root to: "home#index" 就可以了。
以上就是第6步的所有操作。
7、在终端输入以下代码:
rails g devise user
注:以上这个代码是产生 User Model 和 Migration(db/migrate/00_devise_create_users.rb,Migration产生的这个文件,00这个时间戳不一样,其它基本一样。)
8、在终端下输入以下代码:
rails db:migrate
注:以上这个代码是建立users资料表(简单的说就是创建了一个以user为名的的sqlite3数据库表格),你可以使用 DB Browser for SQLit3 软件读取这个数据库,以下图中的是我的项目路径。
&9、创建一个list列表,这个list是用scaffold(脚手架)直接产生出来,这个list作用是演示登录后的客户浏览页面,list具体功能看图片。
& & & 在终端输入以下代码:
rails g scaffold list name idcard phone
& & &接着在终端输入以下代码:
rails db:migrate
&注:以上就是用 rails 的 scaffold 强大的功能生产出一个具有添加、删除、修改、显示的功能,看图:
10、用Atom打开app/controllers/lists_controller.rb,把以下代码输入相应的位置:
before_action :authenticate_user!
注:这个是Devise的提供的方法,验证登录后才能打开这个list页面(第9步的页面)。
11、增加一个注册登录的导航,按下方法操作:
打开app/views/layouts/application.html.erb,输入以下代码:
&% if current_user %&
&%= link_to('登出', destroy_user_session_path, :method =& :delete) %& |
&%= link_to('修改密碼', edit_registration_path(:user)) %&
&% else %&
&%= link_to('註冊', new_registration_path(:user)) %& |
&%= link_to('登入', new_session_path(:user)) %&
12、接下来做权限功能,首先要给数据库的users表增加一个字段,在终端输入以下代码:
rails g migration add_role_to_users
注:这里代码是给数据库的users表增加一个字段 role 。
打开db/migrate/05_add_role_to_users.rb,这个就是刚刚上面的这个代码产生的一个文件,这里的时间戳05和我不一样的。
添加以下代码到这个文件里:
add_column :users, :role, :string
注:这里代码意思是数据库 users 表增加 role 字段,属性为 string 。
然后终端里执行以下代码:
rails db:migrate
13、打开app/models/user.rb文件,增加代码
def admin?
self.role == "admin"
 注:以上代码是admin方法,就是权限判断这个admin字符时用的。
&14、打开app/controllers/application_controller.rb,增加以下代码:
def authenticate_admin
unless current_user.admin?
# flash[:alert] = "Not allow!"
redirect_to root_path
注:这里代码是做一个私有方法,判断登录用户为admin后直接跳转到首页。
&15、打开app/controllers/lists_controller.rb,我这里设置用户的 role 为 admin 时可进入 lists 页面,输入以下代码:
before_action :authenticate_user!
# 這個是 devise 提供的方法,先檢查必須登入
before_action :authenticate_admin # 再檢查是否有權限
注:上面#号就是解释这两个方法的作用。
16、在终端进入你的项目目录,我的是这样的 cd workspace/project ,然后输入rails s,就运行服务器,在你的浏览器打开http://localhost:3000
效果图如上面。
这样就实现了刚才12步操作得出的效果,可以注一个账号,登录试试行?
注册成功后的页面:
17、接下来给刚刚注册的
的记录增加 role 的内容,用 DB Browser for SQLit3 打开项目数据库&
的 role 增加 admin 字符,记得保存操作。
&18、现在给 home#index 页面加一个链接到 lists 。打开&app/views/home/index.html.erb ,输入以下代码:
&%= link_to "Lists", lists_path %&
注:这个代码就是链接到 lists 去的。
&保存后,退出账号再登录进去看看是不是多了个 Lists 。
点击 Lists 进去看看就如下图:
你可以再注册一个账号登录一下看看,这个新的账号肯定会没有 Lists 这个链接,因为这个账号记录没有给增加 role 的 admin 字符,你可以打开数据库看看,目前只能手动添加进去。迟一点我再更新一些功能。&
&19、目前只有admin这个权限判断,接着我们做多一个叫做 client (客户)的权限。首先我们先用 scaffold 建立一个叫做 client 的功能,代码如下面:
rails g scaffold client username sex
注:这里代码就是采用 rails 强大的脚手架功能产生一个 client 的功能,这个功能有 username 和 sex 两个字段。
接着就如下代码:
rails db:migrate
注:以上2行代码就可以生成一整套
的 client 功能。
20、打开&app/controllers/home_controller.rb ,增加以上代码:
before_action :authenticate_user!
注:这个是 devise 提供的方法,先检查必须登录。
21、打开&app/controllers/application_controller.rb ,输入以下代码:
def authenticate_client
unless current_user.client?
# flash[:alert] = "Not allow!"
redirect_to root_path
注:这个是判断当前用户是 client 的方法,和 admin 几乎是一样。同理如果想多加几个角色,就可以使用同样的方法,举一反三。
&22、打开&app/views/home/index.html.erb ,输入以下代码:
&% if current_user.admin? %&
&%= link_to "Lists", lists_path %&
&% elsif current_user.client? %&
&%= link_to "Client", clients_path %&
&% else %&
&% root_path %&
注:这里用了current_user.admin? 和 current_user.client? 方法判断登入的 role 。
&23、再注册一个账号:
24、用 DB Browers for SQLite 打开当前项目数据库,给
的 role 字段增加 client 字符。
登录后就发现,之前 Lists 变成了 Client 了。点一下 Client 看看有什么不一样?
要看看这个权限到底有没有用,你可以登录 & 后,直接在地址栏上把 http://localhost:3000/clients 修改为&http://localhost:3000/lists ,你就会发现马上跳回了&http://localhost:3000/&
小结:以上25个操作基本实现了注册登录和权限判断功能,当然这个方法不是最好的,不过可以应付一些小项目。
接下来我继续把功能完善一些后再写出来吧。
&本教程参考了Ruby on Rails实战圣经,感谢作者ihower的分享。
阅读(...) 评论()Rails 用户权限控制问题,如何优雅的实现? · Ruby China
没用现成的插件,设计了user,group,role,action几张表,用于控制用户的分组、角色,操作等权限组合。比较传统的方法,在程序中考虑这样实现,check(用户ID,操作名称(中文名)),在前台代码中出现中文,似乎不是个好主意,而且需要在每个控制器和方法中写入代码。如何用rails的逻辑去实现,求给个新思路?
不是有cancan吗??
没用过 cancan,我是这么做的,把 action 作为权限控制的最小单位。
permission 模型,表中的每一条记录对应一个权限,字段有权限名称和权限的描述。has_many permission_actions
permission_action模型,belongs_to permission,唯一一个字段是记录action,格式(namespace/controller#action)。
将权限关联到 group,这样可以通过 current_user 验证是否有访问每个 action的权限。
def is_allow_action?(action)
group.permissions.include?(Permission.find_by_action(action))
我觉得 before_filter 就很好了,各个地方的逻辑不同,规则放的位置离得远不好理解。
cancan应该也是用before_filter和action的白名单来实现权限控制的吧。好像最小单位也是action吧。
如果比較複雜邏輯的權限,推薦用
gem 'declarative_authorization'
6楼 已删除
用 cancan 吧, 重复造轮子,何必呢。
rbac真没啥好的,cancan其实也不是很爽
cancan不是很好么
cancan + rolify
后方可回复, 如果你还没有账号请点击这里 。
共收到 10 条回复

我要回帖

更多关于 javaweb用户权限控制 的文章

 

随机推荐