您的位置:首页 > 编程语言 > Go语言

【转】goahead 的认证和自定义登陆页面的cookie使用

2015-06-08 10:31 567 查看
原文地址http://zjf30366.blog.163.com/blog/static/4111645820095305333730/

Author:张继飞

goahead认证,允许下面几种方式。

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.

在开源代码中的定义分别为

NONE 0

FULL 1

BASIC 2

DIGEST 3

使用认证要通过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时不会弹出认证页面)。

认证的好处。服务器发送请求认证后,浏览器通过认证页面进入当前页面后,每访问一个页面都会发送认证:如下:

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同目录的主目录下。如下:

############################

####### cookie.c ###########

############################

#include "webs.h"

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

        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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cookie web goahead