goahead認證,容許下面幾種方式。 javascript
NONE - the URL page cannot be accessed.
FULL - the URL can always be accessed, without authentication.
BASIC - BAA is required before the page can be accessed.
DIGEST - DAA is required before the page can be accessed. java
在開源代碼中的定義分別爲
NONE 0
FULL 1
BASIC 2
DIGEST 3 web
使用認證要經過umconfig.txt文件來分析。
這個文件要與webs可執行程序放在同一目錄下。
TABLE=users
ROW=0
name=admin
password= X3Y
group=Administrator
prot=0
disable=0
ROW=1
name=guest
password=M \ 8
group=Administrator
prot=0
disable=0
TABLE=groups
ROW=0
name=Administrator
priv=4
method=1
prot=0
disable=0
TABLE=access
ROW=0
name=/
method=0
secure=0
group=Administrator 瀏覽器
經過um中的代碼咱們能夠知道,認證方式是由TABLE=groups中的method=1控制,而後纔是TABLE=access中的method=1,這個method
正好對應上面的四種方式(0-3)(能夠本身修改一下就看到了不一樣)。
下面說一下TABLE=access中的 name=/ 列,這就是具體受限區域,也就是說咱們要訪問「/」也就是根目錄時,便會發出請求認證,
若name=/home.asp時,咱們訪問其餘數據(頁面)時,不會出現認證,但訪問home.asp時,服務器便會發送請求認證,瀏覽器彈出
認證頁面(固然,咱們的method爲0或1時不會彈出認證頁面)。 服務器
認證的好處。服務器發送請求認證後,瀏覽器經過認證頁面進入當前頁面後,每訪問一個頁面都會發送認證:以下: cookie
Authorization: Digest username="admin", realm="GoAhead", qop="auth", algorithm="MD5", uri="/goform/Login", nonce="225f1094baa6efcc53957e0750b13c6f", nc=00000004, cnonce="f3d9b39f3cacdbc6bf9ce91ef33eb064", response="294a765c3dfd501b239cd3d0298db32e"
這樣咱們就能夠經過使用username="admin"來對某些頁面進行設置,對某些用戶進行限制,好比某些用戶只能訪問特定的頁面以及
修改特定的功能。 函數
下面就來講說如何使用自定義登陸界面login.asp。
可使用cookie,咱們在服務器端添加wp->cookie的具體信息。
我本身寫了一個添加和獲取cookie的文件,cookie.c和cookie.h,放在與webs.c同目錄的主目錄下。以下: ui
############################
####### cookie.c ###########
############################
#include "webs.h" spa
void ws_set_cookie(webs_t wp, char *name, char *value, int min, char *path,
char *pcOthersInTail)
{
int iLen;
/* 1 is the ; and white space before 'others in tail' */
iLen = strlen(name) + strlen(value) + strlen(path) + 2;
if (pcOthersInTail != NULL)
iLen += strlen(pcOthersInTail);
else
pcOthersInTail = "";
if (min)
{
char acExpireData[64];
struct tm *pstTm;
time_t zTime;
zTime = time(NULL);
zTime += min * 60;
pstTm = gmtime(&zTime);
iLen += strftime(acExpireData, 64, "%A, %d-%m-%Y %H:%M:%S GMT", pstTm); 3d
if (wp->cookie)
bfree(B_L, wp->cookie);
iLen += 20;
fmtAlloc(&wp->cookie, iLen, "%s=%s; Expires=%s; Path=%s; %s",
name, value, acExpireData, path, pcOthersInTail);
}
else
{
if (wp->cookie)
bfree(B_L, wp->cookie);
iLen += 10;
fmtAlloc(&wp->cookie, iLen, "%s=%s; Path=%s; %s", name, value, path,
pcOthersInTail);
}
websSetRequestFlags(wp, wp->flags | WEBS_COOKIE);
}
void ws_clear_cookie(webs_t wp, char *name, char *path)
{
char acExpireData[64];
struct tm *pstTm;
time_t zTime;
zTime = time(NULL);
zTime -= 60;
pstTm = gmtime(&zTime);
strftime(acExpireData, 64, "%A, %d-%m-%Y %H:%M:%S GMT", pstTm);
websWrite(wp, "Set-Cookie: %s=0; Expires=%s; Path=%s\r\n", name, acExpireData, path);
}
int ws_get_cookie(webs_t wp, char *name, char **ppValue, int *pLen)
{
char *pcStr, *pcTmpStr1, *pcTmpStr2;
unsigned short len, tmpLen1, tmpLen2;
if (!wp->cookie || !(wp->flags & WEBS_COOKIE))
return 1;
pcStr = wp->cookie;
len = strlen(pcStr);
while (len)
{
pcTmpStr1 = strchr(pcStr, ';');
tmpLen1 = (pcTmpStr1) ? pcTmpStr1 - pcStr : len;
len -= tmpLen1;
pcTmpStr1 = pcStr;
pcStr += tmpLen1 + 1;
/* get the name */
pcTmpStr2 = strchr(pcTmpStr1, '=');
if (!pcTmpStr2 || pcTmpStr2 >= pcStr)
return 1;
tmpLen2 = pcTmpStr2 - pcTmpStr1;
/* ignore the whitespace */
/* get the name */
if (strncmp(name, pcTmpStr1, tmpLen2))
continue;
/* get the value */
pcTmpStr1 = pcTmpStr2 + 1;
tmpLen2 = pcStr - pcTmpStr1 - 1;
/* ignore the whitespace */
if (!tmpLen2)
return 1;
*ppValue = pcTmpStr1;
*pLen = tmpLen2;
return 0;
}
return 1;
}
############################
####### cookie.h ###########
############################
#ifndef _h_WS_COOKIE
#define _h_WS_COOKIE 1
#ifdef __cplusplus
extern"C"{
#endif
/* set cookie in path with name, value and expire time */
void ws_set_cookie(webs_t wp, char *name, char *value, int min, char *path,
char *pcOthersInTail);
/* clear cookie in 'path' named 'name' */
void ws_clear_cookie(webs_t wp, char *name, char *path);
/* get cookie with specific name */
ZINT ws_get_cookie(webs_t wp, char *name, char **ppValue, int *pLen);
#ifdef __cplusplus
}
#endif
#endif
在websResponse()中添加這麼段代碼,做用是設置cookie字段,往客戶端發送。
if (wp->flags & WEBS_COOKIE)
{
websWrite(wp, T("Set-Cookie: %s\r\n"), wp->cookie);
}
上面已經完成了cookie的設置,下面來實現如何使用cookie,在login頁面點登錄後,執行
Login函數時,咱們便設置cookie,方法以下:
value = websGetVar(wp, T("username"), NULL);
……
ws_set_cookie(wp, "username", value, 0, "/", NULL);
在每個受限頁面的最頂端添加Web_ChkUser()函數,用來防止沒有登陸而直接輸入地址就能訪問頁面。
具體代碼以下:(這是一個asp定義,而Login函數是個form定義)
int Web_ChkUser(int eid, webs_t wp, int argc, char_t **argv)
{
int iVaild = 0;
int iLen;
char *value;
if (ws_get_cookie(wp, "username", &value, &iLen) != 0)
{
websWrite(wp, "<script language=\"javascript\">location='/login.asp'</script>");
return -1;
}
/* compare with admin name */
if (gstricmp(value,&administrator[0]) == 0)
{
/* todo sign the user type to admin */
iVaild = 1;
}
else
{
/* compare with user name */
if (gstricmp(value,&guest[0]) == 0)
{
iVaild = 1;
}
}
if (!iVaild)
{
websWrite(wp, "<script language=\"javascript\">location='/login.asp'</script>");
return -1;
}
return 0;
}
後來出現了個問題,因爲頁面採用層的方式,因此在點提交表單的時候,客戶端瀏覽器發送cookie時,cookie格式爲,
Cookie: username=admin; username=admin,這裏面帶了兩個username,通過分析猜想是兩個頁面同時發送的cookie,由於當前頁面
由兩個頁面組成。而後修改了一下獲取cookie的函數,當發送cookie如上時,只取後面的一個。修改代碼以下:
int ws_get_cookie(webs_t wp, char *name, char **ppValue, int *pLen)
{
char *pcStr, *pcTmpStr1, *pcTmpStr2;
unsigned short len, tmpLen1, tmpLen2;
if (!wp->cookie || !(wp->flags & WEBS_COOKIE))
return 1;
pcStr = wp->cookie;
len = strlen(pcStr);
pcTmpStr1 = strchr(pcStr, ';');
if(pcTmpStr1)
{
pcStr = pcTmpStr1+2;
}
/* get the name */
pcTmpStr2 = strchr(pcStr, '=');
if (!pcTmpStr2)
return 1;
tmpLen1 = pcTmpStr2 - pcStr;
/* ignore the whitespace */
/* get the name */
if (strncmp(name, pcStr, tmpLen1))
return 1;
/* get the value */
pcTmpStr1 = pcTmpStr2 + 1;
tmpLen2 = strlen(pcTmpStr1);
/* ignore the whitespace */
if (!tmpLen2)
return 1;
*ppValue = pcTmpStr1;
*pLen = tmpLen2;
return 0;
}