2

我使用 golang web 框架作为我的 web 框架。但会话不使用。我写的代码如下:

package controllers 

import (
    "fmt"
    "net/http"
    "strconv"

    "GoRBAC/app/base"
    "GoRBAC/app/models"

    r "github.com/revel/revel"
)

type App struct {
    *r.Controller
}

// 首页
func (this App) Index() r.Result {
    userDao := models.NewUserDao()
    user, err := userDao.QueryById(1)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(user)
    return this.Render()
}

// 跳转至登录页面
func (this App) ToLogin() r.Result {
    return this.RenderTemplate("App/login.html")
}

func (this App) Login() r.Result {

    username := this.Params.Get("username")
    password := this.Params.Get("password")
    securityCode := this.Params.Get("securityCode")

    fmt.Println(this.Session["securityCode"])
    fmt.Println(username)
    fmt.Println(password)
    fmt.Println(securityCode)

    if securityCode != this.Session["securityCode"] {
        return this.RenderText("error securityCode")
    } else {
        userDao := models.NewUserDao()
        user, err := userDao.QueryByUsername(username)
        if err != nil || user == nil {
            return this.RenderText("username not exsit")
        } else if user.Password != password {
            return this.RenderText("error password")
        } else {
            delete(this.Session, "securityCode")
            this.RenderText("ok")
        }
    }
    return this.RenderText("ok")
}

// 获取验证码图片
func (this App) GetSecurityCode(timestamp int64) r.Result {
    // 时间戳参数,第一次加载为1,后续加载为当前的时间戳,可以用来验证客户端刷新频率
    // 如:刷新频率过高,直接限制当前客户端等
    fmt.Println("GetSecurityCode", timestamp)

    d := make([]byte, 4)
    s := base.NewLen(4)
    ss := ""
    d = []byte(s)

    for v := range d {
        d[v] %= 10
        ss += strconv.FormatInt(int64(d[v]), 32)
    }

    // 将验证码字符串存入到session
    this.Session["securityCode"] = ss
    this.Session.SetNoExpiration()

    fmt.Println(this.Session["securityCode"])
    fmt.Println(ss)

    this.Response.Status = http.StatusOK
    this.Response.ContentType = "image/png"

    base.NewImage(d, 100, 40).WriteTo(this.Response.Out)

    return this.Render()
}

我在 GetSecurityCode() 方法中设置 session 中的 securityCode 值,该方法用于生成用于登录验证的安全代码

我在方法 Login() 中使用 securityCode 值。但我一无所获

任何可以帮助我的人,我该如何解决这个问题?

谢谢 !!

4

2 回答 2

1

我想知道为什么你的绝对有效的问题被否决了。您描述的问题是已知的。这是一个相关的 GH 问题:https ://github.com/revel/revel/issues/792

临时解决方法是避免直接写入c.Response.Out. 而是使用缓冲区,然后使用以下命令返回它RenderText

this.Response.Status = http.StatusOK
this.Response.ContentType = "image/png"

var buffer bytes.Buffer
base.NewImage(d, 100, 40).WriteTo(&buffer)

return this.RenderText(buffer.String())

或者修改你的GetSecurityCode,这样你就不需要Session了。

于 2015-04-07T09:59:29.743 回答
1

@anonx:谢谢正如你所说,我解决了这个问题:

// 获取验证码图片
func (this App) GetSecurityCode(timestamp int64) r.Result {
// 时间戳参数,第一次加载为1,后续加载为当前的时间戳,可以用来验证客户端刷新频率
// 如:刷新频率过高,直接限制当前客户端等
//fmt.Println("GetSecurityCode", timestamp)

d := make([]byte, 4)
s := base.NewLen(4)
ss := ""
d = []byte(s)

for v := range d {
    d[v] %= 10
    ss += strconv.FormatInt(int64(d[v]), 32)
}

this.Session["securityCode"] = ss
fmt.Println(this.Session["securityCode"])

//this.Response.Status = http.StatusOK
//this.Response.ContentType = "image/png"

buff := &bytes.Buffer{}
base.NewImage(d, 100, 40).WriteTo(buff)

return this.RenderBinary(buff, "img", r.Attachment, time.Now())
}
于 2015-04-10T02:16:54.943 回答