Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
618cf795
Commit
618cf795
authored
Jun 13, 2019
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完善http文件鉴权范例以及注释
parent
42fe7e3d
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
82 行增加
和
5 行删除
+82
-5
server/WebApi.cpp
+31
-1
server/WebHook.cpp
+51
-4
没有找到文件。
server/WebApi.cpp
查看文件 @
618cf795
...
@@ -667,10 +667,40 @@ void installWebApi() {
...
@@ -667,10 +667,40 @@ void installWebApi() {
val
[
"close"
]
=
true
;
val
[
"close"
]
=
true
;
});
});
static
auto
checkAccess
=
[](
const
string
&
params
){
//我们假定大家都要权限访问
return
true
;
};
API_REGIST
(
hook
,
on_http_access
,{
API_REGIST
(
hook
,
on_http_access
,{
//能访问根目录10分钟
#if 0
//能访问根目录以及根目录下所有文件10分钟
val["path"] = "/";
val["path"] = "/";
val["second"] = 10 * 60;
val["second"] = 10 * 60;
#else
//在这里根据allArgs["params"](url参数)来判断该http客户端是否有权限访问该文件
if
(
!
checkAccess
(
allArgs
[
"params"
])){
//无访问权限
val
[
"path"
]
=
""
;
//标记该客户端无权限1分钟,1分钟之内它凭此cookie访问将都无权限
//如果客户端不支持cookie,那么可以根据url参数来追踪用户,请参考kBroadcastTrackHttpClient事件
//如果服务器未处理kBroadcastTrackHttpClient事件,那么ZLMediaKit会根据ip和端口追踪用户
val
[
"second"
]
=
60
;
return
;
}
//只能访问本文件,且只授权10分钟,访问其他文件都要另外授权
if
(
allArgs
[
"is_dir"
].
as
<
bool
>
()){
//访问的是目录,该授权cookie只对该目录有效
val
[
"path"
]
=
(
string
)
allArgs
[
"path"
];
}
else
{
//访问的是文件,那么我们授予客户端访问所在目录的权限
string
dir
=
allArgs
[
"path"
].
substr
(
0
,
allArgs
[
"path"
].
rfind
(
"/"
)
+
1
);
val
[
"path"
]
=
dir
;
}
//该http客户端用户被授予10分钟的访问权限,该权限仅限访问特定目录
val
[
"second"
]
=
10
*
60
;
#endif
});
});
...
...
server/WebHook.cpp
查看文件 @
618cf795
...
@@ -382,11 +382,59 @@ void installWebHook(){
...
@@ -382,11 +382,59 @@ void installWebHook(){
});
});
//由于http是短链接,如果http客户端不支持cookie,那么http服务器就不好追踪用户;
//如果无法追踪用户,那么每次访问http服务器文件都会触发kBroadcastHttpAccess事件,这样的话会严重影响性能
//所以在http客户端不支持cookie的情况下,目前只有两种方式来追踪用户
//1、根据url参数,2、根据ip和端口
//由于http短连接的特性,端口基本上是无法固定的,所以根据ip和端口来追踪用户基本不太现实,所以只剩方式1了
//以下提供了根据url参数来追踪用户的范例
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Broadcast
::
kBroadcastTrackHttpClient
,[](
BroadcastTrackHttpClientArgs
){
auto
&
params
=
parser
.
getUrlArgs
();
if
(
!
params
[
"token"
].
empty
()){
//根据token追踪用户
uid
=
params
[
"token"
];
return
;
}
if
(
!
params
[
"uid"
].
empty
()){
//根据uid追踪用户
uid
=
params
[
"uid"
];
return
;
}
if
(
!
params
[
"user"
].
empty
()){
//根据user追踪用户
uid
=
params
[
"user"
];
return
;
}
if
(
!
params
[
"secret"
].
empty
()){
//根据secret追踪用户
uid
=
params
[
"secret"
];
return
;
}
});
//http客户端访问文件鉴权事件
//开发者应该通过该事件判定http客户端是否有权限访问http服务器上的特定文件
//ZLMediaKit会记录本次鉴权的结果,并且通过设置cookie的方式追踪该http客户端,
//在该cookie的有效期内,该http客户端再次访问该文件将不再触发kBroadcastHttpAccess事件
//如果http客户端不支持cookie,那么ZLMediaKit会通过诸如url参数的方式追踪http客户端
//通过追踪http客户端的方式,可以减少http短连接导致的大量的鉴权事件请求
//在kBroadcastHttpAccess事件中,开发者应该通过参数params(url参数)来判断http客户端是否具有访问权限
//需要指出的是,假如http客户端支持cookie,并且判定客户端没有权限,那么在该cookie有效期内,
//不管该客户端是否变换url参数都将无法再次访问该文件,所以如果判定无权限的情况下,可以把cookie有效期设置短一点
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Broadcast
::
kBroadcastHttpAccess
,[](
BroadcastHttpAccessArgs
){
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Broadcast
::
kBroadcastHttpAccess
,[](
BroadcastHttpAccessArgs
){
if
(
!
hook_enable
||
args
.
_param_strs
==
hook_adminparams
||
hook_http_access
.
empty
()
||
sender
.
get_peer_ip
()
==
"127.0.0.1"
){
if
(
sender
.
get_peer_ip
()
==
"127.0.0.1"
&&
args
.
_param_strs
==
hook_adminparams
){
//这种情况下随便访问,先让他随便访问1分钟,之后可能开启鉴权
//如果是本机或超级管理员访问,那么不做访问鉴权;权限有效期1个小时
invoker
(
"/"
,
60
);
invoker
(
"/"
,
60
*
60
);
return
;
}
if
(
!
hook_enable
||
hook_http_access
.
empty
()){
//未开启http文件访问鉴权,那么允许访问,但是每次访问都要鉴权;
//因为后续随时都可能开启鉴权(重载配置文件后可能重新开启鉴权)
invoker
(
"/"
,
0
);
return
;
return
;
}
}
...
@@ -397,7 +445,6 @@ void installWebHook(){
...
@@ -397,7 +445,6 @@ void installWebHook(){
body
[
"path"
]
=
path
;
body
[
"path"
]
=
path
;
body
[
"is_dir"
]
=
is_dir
;
body
[
"is_dir"
]
=
is_dir
;
body
[
"params"
]
=
parser
.
Params
();
body
[
"params"
]
=
parser
.
Params
();
body
[
"content"
]
=
parser
.
Content
();
for
(
auto
&
pr
:
parser
.
getValues
()){
for
(
auto
&
pr
:
parser
.
getValues
()){
body
[
string
(
"header."
)
+
pr
.
first
]
=
pr
.
second
;
body
[
string
(
"header."
)
+
pr
.
first
]
=
pr
.
second
;
}
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论