goahead 的認證和自定義登錄頁面的cookie使用

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;

}

相關文章
相關標籤/搜索