首先: 永远不要使用md5哈希密码。阅读有关原因的文章,然后使用Go的bcrypt包。您还应该参数化您的SQL查询,否则您将 遭受灾难性的 SQL注入攻击。
无论如何:您需要在此处解决一些问题:
- 您的会话不是“固定”的,而是您将
Path
as 设置为/loginSession
-因此,当用户访问任何其他路径(即/
)时,该会话对该范围无效。
您应该在程序初始化时设置会话存储,并在其中设置选项:
var store = sessions.NewcookieStore([]byte("something-very-secret"))func init() { store.Options = &sessions.Options{ Domain: "localhost", Path: "/", MaxAge: 3600 * 8, // 8 hours HttpOnly: true,}您可能设置更具体路径的原因是,如果登录用户始终在子路由之内,例如
/accounts。就您而言,这不是正在发生的事情。
我应该补充一下,Web检查器中的Chrome的“资源”选项卡(“资源”>“
cookie”)对于调试此类问题非常有用,因为您可以看到cookie的有效期,路径和其他设置。
- 您还在检查
session.Values["email"] == nil
,这是行不通的。Go中的一个空字符串是just""
,并且由于session.Values
是amap[string]interface{},因此需要将assert值键入一个字符串:
即
if val, ok := session.Values["email"].(string); ok { // if val is a string switch val { case "": http.Redirect(res, req, "html/login.html", http.StatusFound) default: http.Redirect(res, req, "html/home.html", http.StatusFound) } } else { // if val is not a string type http.Redirect(res, req, "html/login.html", http.StatusFound) }我们处理“不是字符串”的情况,因此我们很明确地说明如果会话不是我们期望的那样,程序应该怎么做(客户端对其进行了修改,或者我们程序的较旧版本使用了不同的类型)。
- 保存会话时,您没有检查错误。
sessionNew.Save(req, res)
… 应该:
err := sessionNew.Save(req, res) if err != nil { // handle the error case }SessionHandler
在 提供静态文件 之前 ,您应该先获取/验证会话(但是,这样做的方式非常round回):func SessionHandler(res http.ResponseWriter, req *http.Request) {session, err := store.Get(req, "loginSession")if err != nil { // Handle the error}if session.Values["email"] == nil { http.Redirect(res, req, "html/login.html", http.StatusFound)} else { http.Redirect(res, req, "html/home.html", http.StatusFound)}// This shouldn't be here - router isn't scoped in this function! You should set this in your main() and wrap it with a function that checks for a valid session.router.PathPrefix("/").Handler(http.FileServer(http.Dir("../static/")))}



