完善http文件鉴权范例以及注释

This commit is contained in:
xiongziliang 2019-06-13 13:02:30 +08:00
parent 42fe7e3dc5
commit 618cf79569
2 changed files with 82 additions and 5 deletions

View File

@ -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
}); });

View File

@ -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事件中开发者应该通过参数paramsurl参数来判断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(){
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;
} }