在CGI中實現session的想法和實現 (轉)
對於客戶端的每一次登陸,在生成一個session,作為一個在伺服器上,例如在“/tmp”下。
檔案命名為sess_開頭,在加上一個隨機的字串,這個字串稱之為session_id。
在檔案中儲存的內容包括:
1、的最後一次活動時間。(用來檢查使用者是否長時間沒有操作,視為已經退出登陸)。
2、一個隨機的字串。(用來驗證客戶端的身份,這個字串同時作為cookie發往客戶端)。
3、客戶端的IP.
4、實際要儲存的資料。例如使用者的ID,密碼等。
在使用者登陸時,生成這個檔案,並且,將那個隨機字串發到客戶端的cookie.
在以後的每個頁面的超連線,或是FORM中的要跟入session_id.
每個頁面開始,要:
1、檢查是否超時。
2、對比cookie中的字串和session檔案中的,驗證客戶身份。
3、對比客戶端IP和session檔案中的IP,驗證客戶身份。
4、讀出資料,供下面使用
5、重新整理最後活動時間
6、生成新的隨機字串,重新整理session中對應部分,並將其作為cookie發往客戶端。
因為我正在做的專案要求比較高的性,所以我在這方面考慮的比較多些,但我知道這樣肯定還
不是完全安全的。如果誰發現了什麼,麻煩告訴我。
下面是我的部分實現程式碼:
set_session()在登陸是。
start_session()在每個頁面的前面呼叫。
kill_session()在退出登陸是呼叫。
clean_session() 用來刪除過期的session檔案。
#include
#include
#include
#include
#include
#include
#include
#include
#define REMOTE_ADDR1 getenv("REMOTE_ADDR")
#define HTTP_COOKgetenv("HTTP_COOKIE")
char *sess_user_name;
char *sess_user_pwd;
static void print_session_error(char *);
static void clean_session_file();
char *set_session(char *name,char *pwd)
{
char str_now[11];
char hash_key[17];
char *session_id;
time_t now;
FILE *;
char sfp[32];
int i,temp,r;
time(&now);
/**
* clean time out session file
*/
clean_session_file();
/**
* get str_now
*/
sprintf(str_now,"%10d",now);
/**
* get ran hash_key
*/
srand(now);
r = rand();
for(i=0;i<16;i++)
{
srand(r);
r = rand();
hash_key[i] = r%26 + 'a';
}
hash_key[16] = '';
/**
* get more random session_id;
*/
temp = rand();
srand(temp);
r = rand();
session_id = (char*) malloc(17*sizeof(char));
for(i=0;i<16; i++)
{
srand(r);
r = rand();
session_id[i] = r%26 + 'A';
}
session_id[16] = '';
/**
* create session file
*/
strcpy(sfp,"/tmp");
strcat(sfp,"/sess_");
strcat(sfp,session_id);
sf = fopen(sfp,"w");
chmod(sfp,06777);
if( sf == NULL )
{
tc_error_page("can't creat session file");
}
/**
* fputs session file
*/
fputs(str_now,sf);
fputs("n",sf);
fputs(hash_key,sf);
fputs("n",sf);
fputs(REMOTE_ADDR1,sf);
fputs("n",sf);
fputs(name,sf); //sess_user_name
fputs("n",sf);
fputs(pwd,sf); // sess_user_pwd_
fputs("n",sf);
fclose(sf);
/**
* set cookie
*/
printf("Set-Cookie:hash_key=%sn",hash_key);
return session_id;
}
void start_session()
{
int i,j,k;
char *session_id;
FILE *sf;
char sfp[32];
time_t now;
int r;
char buffer[256];
char temp[64];
char str_time[16];
char str_hash_key[20];
char str_client_ip[20];
char *str_array[6];
sess_user_name = (char*)malloc(32*sizeof(char));
sess_user_pwd = (char*)malloc(32*sizeof(char));
str_array[0] = str_time;
str_array[1] = str_hash_key;
str_array[2] = str_client_ip;
str_array[3] = sess_user_name;
str_array[4] = sess_user_pwd;
session_id = cgi_val(entries,"session_id");
/**
* open session file
*/
strcpy(sfp,"/tmp");
strcat(sfp,"/sess_");
strcat(sfp,session_id);
sf = fopen(sfp,"rb+");
if( sf == NULL )
/** can't open session file,maybe session has time out **/
{
print_session_error("1");
exit(1);
}
/**
* read session var
*/
bzero(buffer,256);
fread(buffer,1,256,sf);
for(i=0,j=0,k=0;k<5 && i
if( buffer[i] == 'n' )
{
temp[j] = '';
strcpy(str_array[k],temp);
j = 0;
k ++;
}
else
{
temp[j++] = buffer[i];
}
}
/**
* check active time
*/
time(&now);
if( now - atoi(str_time) > atoi(parse_config_file("session_live_time")) )
{
print_session_error("2");
exit(1);
}
/**
* compare client hash_key to session hash_key
*/
if( HTTP_COOKIE == "" || strcmp( HTTP_COOKIE+9 , str_hash_key ) != 0 )
{
print_session_error("3");
exit(1);
}
/**
* compare client to session ip
*/
if( strcmp( REMOTE_ADDR, str_client_ip ) != 0 )
{
print_session_error("4");
exit(1);
}
/**
* refresh session active time
*/
time(&now);
sprintf(str_time,"%10dn",now);
fseek(sf,0,SEEK_SET);
fputs(str_time,sf);
/**
* get new hash_key
*/
srand(now);
r = rand();
for(i=0;i<16;i++)
{
srand(r);
r = rand();
str_hash_key[i] = r % 26 + 'a';
}
str_hash_key[16] = 'n';
str_hash_key[17] = '';
/**
* refresh session hash_key
*/
fseek(sf,11,SEEK_SET);
fputs(str_hash_key,sf);
fclose(sf);
/**
* send cookie refresh client hash_key
*/
printf("Set-Cookie:hash_key=%s",str_hash_key);
}
void kill_session()
{
char *session_id;
char *session_path;
char sfp[128];
session_id = cgi_val(entries,"session_id");
strcpy(sfp,"/tmp");
strcat(sfp,"/sess_");
strcat(sfp,session_id);
remove(sfp);
}
void clean_session_file()
{
DIR *pdir;
struct dirent *ent;
char *path;
char *filename;
char filepath[64];
int fd;
char str_time[11];
time_t now;
path = "/tmp";
pdir = opendir(path);
if(pdir != NULL)
{
while( ent =readdir(pdir) )
{
filename = ent->d_name;
if( strncmp(filename,"sess_",5)==0 )
{
strcpy(filepath,path);
strcat(filepath,"/");
strcat(filepath,filename);
fd = open(filepath,O_RDONLY);
read(fd,str_time,10);
time(&now);
if( now - atoi(str_time) > atoi(parse_config_file("session_live_time")) )
{
remove(filepath);
}
close(fd);
}
}
}
closedir(pdir);
}
void print_session_error(char *n)
{
printf("Content-type:text/htmlnn");
printf("
print_title("請重新登陸!");
printf("n");
printf("
n");printf("對不起,請重新登陸。
n");
printf("你長時間沒有操作,登陸已經超時。或者是發生了錯誤。
n");
printf("如果是後者,請與管理人員聯絡。n");
printf("<!--%s-->",n);
printf("");
printf("n");
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-990868/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Tomcat中的session實現TomcatSession
- cookie與session的區別以及在Django中的實現CookieSessionDjango
- Cookie、Session、JWT在koa中的應用及實現原理CookieSessionJWT
- Cloud Foundry Session Affinity(Sticky Session)的實現CloudSession
- 在SpringBoot專案中整合SpringSession,基於Redis實現對Session的管理和事件監聽Spring BootGseSessionRedis事件
- Spring MVC 中檢視的實現原理,在Spring MVC 中實現重定向和轉發,以及訪問靜態資源SpringMVC
- 在 react-native 中實現 Promise 和 AsyncStorageReactPromise
- 在 GPUImage 中實現 ColorConversionGPUUI
- 在 Zig 中實現介面
- 通過redis實現session共享RedisSession
- 分享一個session過期後根據guard跳轉的實現Session
- NFT 的建立和轉移功能實現
- 如何基於 echarts 在柱狀圖或條形圖上實現轉換率?(有想法嗎?)Echarts
- [譯] Story 中 Type Mode 在 iOS 和 Android 上的實現iOSAndroid
- 深入解析多型和方法呼叫在JVM中的實現多型JVM
- 現在的中國遊戲圈,能有多現實?遊戲
- 在幕後看看Swift中的Map,Filter和Reduce的實現SwiftFilter
- 分散式系統Session 實現方式分散式Session
- Java Servlet session實現登入退出JavaServletSession
- 快速實現 Tomcat 叢集 Session 共享TomcatSession
- 決策樹在sklearn中的實現
- Hooks API 在 Vue 中的實現分析HookAPIVue
- Percolator模型及其在TiKV中的實現模型
- python實現中文和unicode轉換PythonUnicode
- 用setjmp和longjmp實現跳轉
- SpringBoot2.x 整合Spring-Session實現Session共享Spring BootSession
- Flutter中實現無Context跳轉FlutterContext
- PHP中實現頁面跳轉PHP
- 在後端中如何實現冪等和去重?後端
- 短影片商城系統,session和cookie實現登入SessionCookie
- 在Linux中,如何實現檔案系統的快照和克隆?Linux
- C#二維陣列在SLG中的實現和使用C#陣列
- 在Lua中實現Rust物件的繫結Rust物件
- Lru在Rust中的實現, 原始碼解析Rust原始碼
- 設計模式在Python中的完美實現設計模式Python
- 另類用法 hyperf/session 實現 API tokenSessionAPI
- 基於 Session 實現簡訊登入Session
- Oracle Session每日統計功能實現XLAMOracleSession
- 在Swift中實現撤銷功能Swift