公司vpn登录本地web,cookie超时问题,
描述如下:
本地web登录正常 超时后再次登录正常
vpnweb登录正常 超时后再次登录不正常(操作其他按钮就退出来了)
后来查是cgi的env变量在获取vpn通道的web地址不正确:
cgiGetenv(&cgiRemoteAddr, "REMOTE_ADDR");
cgiGetenv(&cgiRemoteIdent, "REMOTE_IDENT");
问题产生流程:
登录时拿到的ip:192.168.1.99
登录后页面校验拿到的ip:10.60.0.220,如果当前没超时并刷新页面则计时清0
认为有两个地址在同时登录,超时计时从0开始,所以第一次登录操作页面一直正常。
接下来,超时退出了,再次登录:
登录时拿到的ip:192.168.1.99,由于第一次登录,超时计时清0登录后页面校验拿到的ip:10.60.0.220,由于之前已经超时,计时没办法清0,计时数字不断变大
所以超时(5分钟)后再次登录成功,但是点选其他界面就会回归login界面
总的来说,要是REMOTE_ADDR = 192.168.1.99”和HTTP_COOKIE中的“domain=10.60.0.220”的值一致,就不会出现这个异常了。
源码我修复不了,就在应用层避免吧,设置如果超时则清空之前记录的cookie,回归到第一次,先理清思路,下次和别人讲解才能流畅一些。
save_cookie():自定义函数,登录时调用此函数,并保存在磁盘中,登陆后的每个操作也都会调用这个函数,以检查cookie是否超时;
函数内的逻辑如下;
/*****************************************************************************
Prototype : save_session
Description : 保存浏览器cookie, cookie时间戳使用uptime
: 所有cookie信息保存内存中
Input : int *pcSession
Output : None
Return Value : static char
Calls :
Called By :
*****************************************************************************/
static int save_cookie(struct cookie *cookie)
{
struct sysinfo info;
FILE *pfdata;
unsigned int len;
unsigned int loop;
unsigned int flag;
info.uptime=0;
sysinfo(&info);
cookie->uitime=info.uptime;
len=sizeof(struct cookie) * COOKIE_NUMS;
memset(cookies, 0, len);
if((pfdata=fopen(COOKIES_PATH, "r+")))
{
fread(cookies, len, 1, pfdata);
fclose(pfdata);
}
/* 查询 */
flag=0;
for(loop=0;loop<COOKIE_NUMS;loop++)
{
if((0 == strcmp(cookie->aucname, cookies[loop].aucname))
&& (0 == strcmp(cookie->aucdomain, cookies[loop].aucdomain)))
{
if((cookie->uitime-cookies[loop].uitime<=cgiTimeouts) || (cookie->flag == COOKIE_SET_FLAG))
{
cookies[loop].uitime=cookie->uitime;
break;
}
else
{
lcgic_log(CGI_LOG_WARN, "the cookie is timeout.");
/* 【新增】超时则清空/tmp/.sessions 文件,使用通过vpn登陆本地web,超时后登陆不上去问题 */
system("echo > "COOKIES_PATH"");
return SessionTimeoutFailed;
}
}
flag++;
}
if((pfdata=fopen(COOKIES_PATH, "w+")))
{
fwrite(cookies, len, 1, pfdata);
fclose(pfdata);
}
return SessionSuccess;
}
以下表格部分是CGI的环境变量,在其他文章看到的,比较有用就摘抄过来了:
CGI环境变量在CGI程序启动时初始化,在结束时销毁。
当一个CGI程序不是被HTTP服务器调用时,它的环境变量几乎是系统环境变量的复制。
当这个CGI程序被HTTP服务器调用时,它的环境变量就会多了以下关于HTTP服务器、客户端、CGI传输过程等项目。
与请求相关的环境变量 | REQUEST_METHOD | 服务器与CGI程序之间的信息传输方式 |
QUERY_STRING | 采用GET时所传输的信息 | |
CONTENT_LENGTH | STDIO中的有效信息长度 | |
CONTENT_TYPE | 指示所传来的信息的MIME类型 | |
CONTENT_FILE | 使用Windows HTTPd/WinCGI标准时,用来传送数据的文件名 | |
PATH_INFO | 路径信息 | |
PATH_TRANSLATED | CGI程序的完整路径名 | |
SCRIPT_NAME | 所调用的CGI程序的名字 | |
与服务器相关的环境变量 | GATEWAY_INTERFACE | 服务器所实现的CGI版本 |
SERVER_NAME | 服务器的IP或名字 | |
SERVER_PORT | 主机的端口号 | |
SERVER_SOFTWARE | 调用CGI程序的HTTP服务器的名称和版本号 | |
与客户端相关的环境变量 | REMOTE_ADDR | 客户机的主机名 |
REMOTE_HOST | 客户机的IP地址 | |
ACCEPT | 例出能被次请求接受的应答方式 | |
ACCEPT_ENCODING | 列出客户机支持的编码方式 | |
ACCEPT_LANGUAGE | 表明客户机可接受语言的ISO代码 | |
AUTORIZATION | 表明被证实了的用户 | |
FORM | 列出客户机的EMAIL地址 | |
IF_MODIFIED_SINGCE | 当用get方式请求并且只有当文档比指定日期更早时才返回数据 | |
PRAGMA | 设定将来要用到的服务器代理 | |
REFFERER | 指出连接到当前文档的文档的URL | |
USER_AGENT | 客户端浏览器的信息 |
CONTENT_TYPE:如application/x-www-form-urlencoded,表示数据来自HTML表单,并且经过了URL编码。
ACCEPT:客户机所支持的MIME类型清单,内容如:”image/gif,image/jpeg”
REQUEST_METHOD:它的值一般包括两种:POST和GET,但我们写CGI程序时,最后还要考虑其他的情况。
关于HTTP_COOKIE比较特殊:
如果你在一台支持COOKIE的客户端设置了COOKIE,当这个客户端在次来访问时,浏览器会向你的CGI所在的WEB服务器发送一条HTTP响应头,这个响应头为:
Cookie:name1=value;name2=value2;exprires=DATE;PATH=PATH;domiam=DOMAIN_NAME;SECURE
根据这个HTTP响应头WEB服务器的环境变量 HTTP_COOKIE=:name1=value;name2=value2
我们对这个环境变量的内容进行分解就可以的到我我们要的信息。