主要用途:用户登录了,某个接口可能只有超级管理员才能访问,普通用户不能访问
案列:出版社的所有接口,必须登录,而且是超级管理员才能访问
分析步骤
第一步:写一个类,继承BasePermission
第二步:重写has_permission方法
第三步:在方法校验用户时候有权限(request.user就是当前登录用户)
第四步:如果有权限,返回True,没有权限,返回FALSE
第五步:self.message 是给前端的提示信息
第六步:局部使用,全局使用,局部禁用
model.py
class User(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=32)
user_type = models.IntegerField(default=3, choices=((1, '超级管理员'), (2, '普通用户'), (3, '2b用户')))
def __str__(self):
return self.username
permission.py
from rest_framework.permissions import BasePermission
class UserTypePermission(BasePermission):
def has_permission(self, request, view):
# 只有超级管理员有权限
if request.user.user_type == 1:
return True # 有权限
else:
"""
self.message = '普通用户和2b用户都没有权限'
self.message = '您是:%s 用户,您没有权限'%request.user.get_user_type_display()
"""
return False # 没有权限
"""
self.message = '普通用户和2b用户都没有权限'
返回给前端的提示是什么样
self.message = '您是:%s 用户,您没有权限'%request.user.get_user_type_display()
使用了choice后,user.user_type 拿到的是数字类型,想变成字符串 user.get_user_type_display()
"""

view.py
# 导入我们所写的那个权限文件
from .permission import UserTypePermission
# 要验证必须要登录,下面的这种方式是局部权限使用
class PublishView(ViewSetMixin, ListCreateAPIView):
# 登录验证
authentication_classes = [LoginAuth, ]
# 权限验证
permission_classes = [UserTypePermission, ]
queryset = Publish.objects.all()
serializer_class = PublishSerializer
class PublishDetailView(ViewSetMixin, RetrieveUpdateDestroyAPIView):
# 登录验证
authentication_classes = [LoginAuth, ]
# 权限验证
permission_classes = [UserTypePermission, ]
queryset = Publish.objects.all()
serializer_class = PublishSerializer
settings.py
全局权限验证:(要在setting.py文件中配置)
全局验证需要注意的是在登录的时候需要添加局部禁用
permission_classes = []
authentication_classes = []
REST_FRAMEWORK = {
# 'DEFAULT_AUTHENTICATION_CLASSES': ['app01.auth.LoginAuth', ]
'DEFAULT_PERMISSION_CLASSES': ['app01.permission.UserTypePermission', ]
}
# 全局的加上以后局部的就可以注释掉了
内置权限类
注意如果要使用内置的权限类就需要用全套(认证和权限都要用内置的)
# 演示一下内置权限的使用:IsAdminUser,控制是否对网站后台有权限的人
# 1 创建超级管理员
# 2 写一个测试视图类
from rest_framework.permissions import IsAdminUser
from rest_framework.authentication import SessionAuthentication
class TestView3(APIView):
authentication_classes=[SessionAuthentication,]
permission_classes = [IsAdminUser] # 这两个都要用内置的
def get(self,request,*args,**kwargs):
return Response('这是22222222测试数据,超级管理员可以看')
# 3 超级用户登录到admin,再访问test3就有权限
# 4 正常的话,普通管理员,没有权限看(判断的是is_staff字段)
认证,权限都通过以后,我们可以限制某个接口的访问频率,防止有人恶意攻击网站,一般根据ip或者用户限制
案例:无论是否登录和是否有权限,都要限制访问的频率,比如一分钟访问3次
分析步骤:
第一步:写一个类:继承SimpleRateThrottle
第二步:重写get_cache_key,返回唯一的字符串,会以这个字符串做频率限制
第三步:写一个类属性scope=‘随便写’,必须要跟配置文件对象
第四步:配置文件中写
'DEFAULT_THROTTLE_RATES': {
'随意写': '3/m' # 3/h 3/s 3/d
}
第五步:局部配置,全局配置,局部禁用
throttling.py(SimpleRateThrottle)
from rest_framework.throttling import BaseThrottle, SimpleRateThrottle
# 我们继承SimpleRateThrottle去写,而不是继承BaseThrottle去写
class TimeThrottling(SimpleRateThrottle):
# 类属性,这个类属性可以随意命名,但要跟配置文件对应
scope = 'throttling'
def get_cache_key(self, request, view):
"""
# 返回什么,频率就以什么做限制
# 可以通过用户id限制
# 可以通过ip地址限制
"""
return request.META.get('REMOTE_ADDR') # 这个就是根据用户ip进行限制
局部配置
class PublishView(ViewSetMixin, ListCreateAPIView):
authentication_classes = [LoginAuth, ]
# permission_classes = [UserTypePermission, ]
# 局部频率验证,每分钟只能访问五次
throttle_classes = [TimeThrottling, ]
queryset = Publish.objects.all()
serializer_class = PublishSerializer
class PublishDetailView(ViewSetMixin, RetrieveUpdateDestroyAPIView):
authentication_classes = [LoginAuth, ]
# permission_classes = [UserTypePermission, ]
# 局部频率验证,每分钟只能访问五次
throttle_classes = [TimeThrottling, ]
queryset = Publish.objects.all()
serializer_class = PublishSerializer
全局配置
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.TimeThrottling', ],
'DEFAULT_THROTTLE_RATES': {
'throttling': '5/m' # 一分钟访问5次
}
}
限制未登录用户
# 全局使用 限制未登录用户1分钟访问5次
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
),
'DEFAULT_THROTTLE_RATES': {
'anon': '3/m',
}
}
#views.py
from rest_framework.permissions import IsAdminUser
from rest_framework.authentication import SessionAuthentication,BasicAuthentication
class TestView4(APIView):
authentication_classes=[]
permission_classes = []
def get(self,request,*args,**kwargs):
return Response('我是未登录用户')
# 局部使用
from rest_framework.permissions import IsAdminUser
from rest_framework.authentication import SessionAuthentication,BasicAuthentication
from rest_framework.throttling import AnonRateThrottle
class TestView5(APIView):
authentication_classes=[]
permission_classes = []
throttle_classes = [AnonRateThrottle]
def get(self,request,*args,**kwargs):
return Response('我是未登录用户,TestView5')
限制登录用户的访问频次
全局:在setting中
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
),
'DEFAULT_THROTTLE_RATES': {
'user': '10/m',
'anon': '5/m',
}
局部配置:
在视图类中配一个就行
大家好,我正在尝试设置一个开发环境,并且我一直在关注以下教程:Linktotutorial我做得不是很好,除了最基本的版本控制内容外,我对终端命令没有任何实际经验。我点击了第一个链接并尝试运行source~/.bash_profile我得到了错误;mkdir:/usr/local/rbenv/shims:权限被拒绝mkdir:/usr/local/rbenv/versions:权限被拒绝现在每次我加载终端时都会出现错误。bash_profile的内容;exportPATH=/usr/local/rbenv/bin:$PATHexportRBENV_ROOT=/usr/local/rbe
我正在为我的用户实现一些rubyonrails代码推特内容。我正在创建正确的oauth链接...类似http://twitter.com/oauth/authorize?oauth_token=y2RkuftYAEkbEuIF7zKMuzWN30O2XxM8U9j0egtzKv但在我的测试帐户授予对twitter的访问权限后,它会弹出一个页面,上面写着“您已成功授予对.我不知道用户应该在哪里输入此PIN以及他们为什么必须这样做。我认为这不是必要的步骤。Twitter应该将用户重定向到我在应用程序设置中提供的回调URL。有谁知道为什么会这样?更新我找到了thisarticle声明我需
我正在关注Ryan的RailsCast第339集。我已经安装了rbenv并且可以运行ruby-v。我退出了我的session,当我试图返回时(通过root的sudeployer,我得到了这个错误/home/deployer/.rbenv/bin/rbenv:line20:cd:/root:Permissiondenied这是rbenv文件:#!/usr/bin/envbashset-e[-n"$RBENV_DEBUG"]&&set-xresolve_link(){$(type-pgreadlinkreadlink|head-1)"$1"}abs_dirname(){localcwd="
有没有一种有效的方法来做到这一点。我有一个数组a=[1,2,2,3,1,2]我想按升序输出出现的频率。示例[[3,1],[1,2],[2,3]]这是我的ruby代码。b=a.group_by{|x|x}out={}b.eachdo|k,v|out[k]=v.sizeendout.sort_by{|k,v|v} 最佳答案 a=[1,2,2,3,1,2]a.each_with_object(Hash.new(0)){|m,h|h[m]+=1}.sort_by{|k,v|v}#=>[[3,1],[1,2],[2,3]]
如何使用Capistrano将Rails应用程序部署到无法访问外部网络或存储库的生产或暂存服务器?我已经设法完成部署的一半,并意识到Capistrano没有在我的本地机器上下载gitrepo,但它首先连接到远程服务器并尝试在那里下载Git存储库。我希望有一个类似Javaee的构建系统,其中创建可交付成果并将该可交付成果发送到服务器。就像您构建.ear文件并将其部署到您想要的任何服务器上一样。显然在RoR中,你被迫(据我所知)在该服务器上构建应用程序,在那里创建一个gem存储库,在那里克隆最新的分支等等。有什么方法可以将准备运行的包发送到远程服务器吗? 最佳答
我在运行Ubuntu10.04LTS的远程VPS机器上以生产模式运行RubyonRails3.0.9(在开发模式下,我在MACOSSnow上使用RoRLeopard),我想知道如何管理以下场景。我使用Apache2和PhusionPassenger并且我将虚拟主机设置为如下所示:ServerNameproject_name.comDocumentRoot/srv/www/project_name.com/publicAllowOverrideallOptions-MultiViews此外,我使用Paperclipgem,由于网上很多人在生产模式下使用它,我在处理(图像)文件时遇到以下错
学习Ruby和Rails大约2周后,我发现自己经常使用File类来处理File.join、File.打开等。然后我遇到了File.copy的需求,却发现不存在这样的方法。再仔细一看,发现了Rails的FileUtils类,现在我有点困惑。当然有差异,但也有看似冗余的地方。在存在差异的地方,一个比另一个更受欢迎吗?为什么两者都存在(仅仅是为了处理Ruby核心类中的遗漏)?我只是想了解一下这些事情是如何协同工作或发生冲突的,以便我知道如何继续前进。谢谢。 最佳答案 FileUtils是Ruby核心API的一部分。它不是特定于Rails的
class之间有什么区别?和Class.new&module和Module.new?我知道:Class.new/Module.new创建一个匿名class/module.当我们第一次将它分配给常量时,它变成了那个class的名称。/module.class/module自动执行此操作。当我们想要继承时,我们可以传递一个参数:Class.new(ancestor).当我们不指定祖先时,它被设置为Object.class使用此语法:classAClass.new返回object.classA返回nil.同样适用于module秒。我错过了什么吗? 最佳答案
我创建了一个包含自定义gemset的项目特定.rvmrc文件(使用命令rvm--rvmrc--create1.9.2@registration):#excerptof.rvmrc...environment_id="ruby-1.9.2@registration"if[[-d"${rvm_path:-$HOME/.rvm}/environments"\&&-s"${rvm_path:-$HOME/.rvm}/environments/$environment_id"]]then\."${rvm_path:-$HOME/.rvm}/environments/$environment_id
我有一个嵌套的数字数组,排列如下:ids=[[5,8,10],[8,7,25],[15,30,32],[10,8,7]]我只需要一个包含所有键的数组,无需重复,所以我使用了这个:ids=ids.flatten.uniq产生这个:ids=[5,8,10,7,25,15,30,32]由于我使用了.uniq,它消除了重复值。但是,我想根据它们在子数组中出现的频率来对值进行排序,而不是它们碰巧处于的顺序——所以像这样:ids=[8,10,7,5,25,15,30,32] 最佳答案 应该这样做:ids.flatten.group_by{|i|