使用大猩猩会话网络工具包时,不会跨请求维护会话变量。当我启动服务器并输入localhost:8100
/时,由于会话值不存在,页面被定向到login.html。登录后,我在商店中设置了会话变量,页面被重定向到home.html。但是,当我打开一个新选项卡并键入localhost:8100
/时,应使用已存储的会话变量将页面定向到home.html,但应将页面重定向到login.html。以下是代码。
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"github.com/gocql/gocql"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
"net/http"
"time"
)
var store = sessions.NewCookieStore([]byte("something-very-secret"))
var router = mux.NewRouter()
func init() {
store.Options = &sessions.Options{
Domain: "localhost",
Path: "/",
MaxAge: 3600 * 1, // 1 hour
HttpOnly: true,
}
}
func main() {
//session handling
router.HandleFunc("/", SessionHandler)
router.HandleFunc("/signIn", SignInHandler)
router.HandleFunc("/signUp", SignUpHandler)
router.HandleFunc("/logOut", LogOutHandler)
http.Handle("/", router)
http.ListenAndServe(":8100", nil)
}
//handler for signIn
func SignInHandler(res http.ResponseWriter, req *http.Request) {
email := req.FormValue("email")
password := req.FormValue("password")
//Generate hash of password
hasher := md5.New()
hasher.Write([]byte(password))
encrypted_password := hex.EncodeToString(hasher.Sum(nil))
//cassandra connection
cluster := gocql.NewCluster("localhost")
cluster.Keyspace = "gbuy"
cluster.DefaultPort = 9042
cluster.Consistency = gocql.Quorum
session, _ := cluster.CreateSession()
defer session.Close()
//select query
var firstname string
stmt := "SELECT firstname FROM USER WHERE email= '" + email + "' and password ='" + encrypted_password + "';"
err := session.Query(stmt).Scan(&firstname)
if err != nil {
fmt.Fprintf(res, "failed")
} else {
if firstname == "" {
fmt.Fprintf(res, "failed")
} else {
fmt.Fprintf(res, firstname)
}
}
//store in session variable
sessionNew, _ := store.Get(req, "loginSession")
// Set some session values.
sessionNew.Values["email"] = email
sessionNew.Values["name"] = firstname
// Save it.
sessionNew.Save(req, res)
//store.Save(req,res,sessionNew)
fmt.Println("Session after logging:")
fmt.Println(sessionNew)
}
//handler for signUp
func SignUpHandler(res http.ResponseWriter, req *http.Request) {
fName := req.FormValue("fName")
lName := req.FormValue("lName")
email := req.FormValue("email")
password := req.FormValue("passwd")
birthdate := req.FormValue("date")
city := req.FormValue("city")
gender := req.FormValue("gender")
//Get current timestamp and format it.
sysdate := time.Now().Format("2006-01-02 15:04:05-0700")
//Generate hash of password
hasher := md5.New()
hasher.Write([]byte(password))
encrypted_password := hex.EncodeToString(hasher.Sum(nil))
//cassandra connection
cluster := gocql.NewCluster("localhost")
cluster.Keyspace = "gbuy"
cluster.DefaultPort = 9042
cluster.Consistency = gocql.Quorum
session, _ := cluster.CreateSession()
defer session.Close()
//Insert the data into the Table
stmt := "INSERT INTO USER (email,firstname,lastname,birthdate,city,gender,password,creation_date) VALUES ('" + email + "','" + fName + "','" + lName + "','" + birthdate + "','" + city + "','" + gender + "','" + encrypted_password + "','" + sysdate + "');"
fmt.Println(stmt)
err := session.Query(stmt).Exec()
if err != nil {
fmt.Fprintf(res, "failed")
} else {
fmt.Fprintf(res, fName)
}
}
//handler for logOut
func LogOutHandler(res http.ResponseWriter, req *http.Request) {
sessionOld, err := store.Get(req, "loginSession")
fmt.Println("Session in logout")
fmt.Println(sessionOld)
if err = sessionOld.Save(req, res); err != nil {
fmt.Println("Error saving session: %v", err)
}
}
//handler for Session
func SessionHandler(res http.ResponseWriter, req *http.Request) {
router.PathPrefix("/").Handler(http.FileServer(http.Dir("../static/")))
session, _ := store.Get(req, "loginSession")
fmt.Println("Session in SessionHandler")
fmt.Println(session)
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)
}
}
有人可以告诉我我在做什么错。提前致谢。
首先: 永远不要使用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
是a map[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/")))
}
问题内容: 我正在使用Go创建一个简单的Web应用程序,用于会话和路由的大猩猩,以及用于模板的小胡子。我认为登录有问题,我认为这是IE接受Cookie的问题。该问题仅在Internet Explorer上出现,否则登录在Chrome中可以正常使用。这是我的代码: 使用IE登录时,由于会话值“ username”为nil,用户将被直接重定向回登录页面,而在Chrome中,正确定义了用户名并提供了索引
问题内容: 我已经设置了Go rest api。并在登录时执行此操作: 为了检查会话,我有这样的东西: 如果我执行邮递员的请求,效果很好,但是当我从客户那里收到请求时,我会得到401。你们中的任何人是否经历过类似的事情?该商店是一个CookieStore。 我已经检查了ID,将sessionId变量替换为静态字符串。大猩猩会话使用大猩猩上下文注册一个新请求,当我这样做时,来自邮递员的请求不为空,但
大象与猩猩 是o2o平台全套解决方案,现将Wechat h5、android、iOS三套代码正式开源。
问题内容: 在用go编写的HTTP服务器中,我使用大猩猩/多路复用器进行路由, 我想使用(和/或其他“中间件”),但我不知道该在哪里放置它们。 明确说明: 我通过创建一个新的路由器 通过类似的电话添加我的路线 我通过和创建服务器 为此,我可以在哪里插入或任何其他中间件? 问题答案: 这是您可以执行的操作: 如果您有多个HTTP处理程序,则可以将它们堆叠起来:
问题内容: 我有一个使用AJAX加载新php文件并更新显示的单页网站。 我从主页开始php会话,但是当我使用ajax更新内部html时,我需要这些会话变量来加载新的php文件。 这篇文章与此类似:PHP会话变量未保留。但是我检查了一下,我的php.ini有 主页PHP: 在用户输入之后,我使用ajax调用php文件并加载页面的一个小节: 有人可以告诉我我缺少哪些重要步骤吗?谢谢。 更新: 在主页和
来自WebSocket RFC的片段: 要使用状态代码(第7.4节)/code/和可选关闭原因(第7.1.6节)/reason/启动WebSocket关闭握手,endpoint必须发送关闭控制帧,如第5.5节所述。1,其状态代码设置为/code/,关闭原因设置为/reason/。一旦endpoint发送和接收到关闭控制帧,该endpoint应按照第7.1节中的定义关闭WebSocket连接。1.