- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在为我认识的几个人构建一个小型晚餐/计划管理应用程序(使用微服务)。目的是每个人都可以登录自己的帐户,然后可以使用不记名 token (JWT) 向其他服务进行身份验证。
此不记名 token 存储在 cookie 中。但是,设置后我找不到这个cookie,我尝试再次检索它。
最终导致错误
http: named cookie not present
为什么请求的响应体是空的?为什么我的 GET 请求没有发送任何 cookie?我该如何解决这个问题?
我在网上搜索了一下并尝试了以下操作
网络/http cookie:看起来最简单的实现,也是我在这里展示的那个。看起来这个简单的例子应该可行。
Cookiejar 实现:我尝试使用 cookiejar 实现来设置和检索来自浏览器和 postman 的 cookie,但结果相同。 https://golang.org/pkg/net/http/cookiejar/?m=all#New 中描述了我使用的 cookiejar 实现
设置为特定的 URL 和额外的 GET 请求:我试图将 cookie 放在我域中的不同特定 URL 上。在某些时候,似乎只能从某个特定的绝对 URL 检索 cookie,但事实并非如此。
httputil DumpRequestOut:我发现net/http的工具包有一个函数叫做DumpRequestOut,这个函数可能已经可以从请求中提取body,但是这个也是空的。
将 cookie 的“安全”标志设置为 false:我发现安全标志使 cookie 无法读取的建议。不幸的是,更改安全标志没有任何效果。
Postman 清楚地表明 cookie 确实存在。我的浏览器 (firefox) 也显示 cookie 存在,但它们被赋予了一个相当抽象的名称。可以在 https://www.getpostman.com/collections/fccea5d5dc22e7107664 找到 Postman 请求。
如果我尝试使用来自 golang 的“net/http”包检索 cookie,响应主体会变成空的。
我设置 session token 并在我验证用户/密码组合后直接重定向客户端。
// SetTokenAndRedirect sets an access token to the cookies
func SetTokenAndRedirect(w http.ResponseWriter, r *http.Request, db *mgo.Session, u *user.User, redirectURL string) *handler.AppError {
// Generate a unique ID for the session token.
tokenID := uuid.Must(uuid.NewV4()).String()
//set the expiration time (found in config.config.go)
expirationTime := time.Now().Add(config.ExpireTime)
// Set the cookie with the JWT
http.SetCookie(w, &http.Cookie{
Name: config.AccessTokenName,
Value: createToken(u.UserID, expirationTime, tokenID, r.Header.Get("User-Agent")),
Expires: expirationTime,
HttpOnly: true,
Secure: false,
})
// Redirects user to provided redirect URL
if redirectURL == "" {
return handler.AppErrorf(417, nil, "No redirect URL has been provided")
}
http.Redirect(w, r, redirectURL, 200)
return nil
}
我尝试如下验证传入请求和 JWT token 。
// All handlers will have this adapted serveHTTP function
func (fn AppHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := Authorize(w, r); err != nil {
http.Error(w, fmt.Sprintf("Not Authorized: %v", err), http.StatusUnauthorized)
return
}
if e := fn(w, r); e != nil { // e is *appError, not os.Error.
log.Printf("Handler error: status code: %d, message: %s, underlying err: %#v",
e.Code, e.Message, e.Error)
http.Error(w, e.Message, e.Code)
}
}
// Claims defines what will be stored in a JWT access token
type Claims struct {
ProgramVersion string `json:"programVersion"`
UserAgent string `json:"userAgent"`
jwt.StandardClaims
}
// Authorize checks if the jwt token is valid
func Authorize(w http.ResponseWriter, r *http.Request) error {
c, err := r.Cookie("access_token")
if err != nil {
if err == http.ErrNoCookie {
// The program returns this error
return err
}
return err
}
tokenString := c.Value
claim := &Claims{}
tkn, err := jwt.ParseWithClaims(tokenString, claim, func(tkn *jwt.Token) (interface{}, error) {
return config.JwtSigningSecret, nil
})
if !tkn.Valid {
return err
}
if err != nil {
if err == jwt.ErrSignatureInvalid {
return err
}
return err
}
// JWT token is valid
return nil
}
设置cookie时请求结构如下
// Pretty printed version
Host: localhost:8080
content-type: application/json
user-agent: PostmanRuntime/7.11.0
cache-control: no-cache
accept-encoding: gzip, deflate
content-length: 68
connection: keep-alive
accept: */*
postman-token: 36268859-a342-4630-9fb4-c286f76d868b
cookie: access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcm9ncmFtVmVyc2lvbiI6IjEuMC4wIiwidXNlckFnZW50IjoiUG9zdG1hblJ1bnRpbWUvNy4xMS4wIiwiZXhwIjoxNTU2MjA0MTg3LCJqdGkiOiJlZDlmMThhZi01NTAwLTQ0YTEtYmRkZi02M2E4YWVhM2M0ZDEiLCJpYXQiOjE1NTYyMDM1ODcsImlzcyI6ImdrLmp3dC5wcm9maWxlU2VydmljZS5hIn0.bssnjTZ8woKwIncdz_EOwYbCtt9t6V-7PmLxfq7GVyo
// Raw Version
&{POST /auth/users/login?redirect=/ HTTP/1.1 1 1 map[Cache-Control:[no-cache] Postman-Token:[d33a093e-c7ab-4eba-8c1e-914e85a0d289] Cookie:[access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcm9ncmFtVmVyc2lvbiI6IjEuMC4wIiwidXNlckFnZW50IjoiUG9zdG1hblJ1bnRpbWUvNy4xMS4wIiwiZXhwIjoxNTU2MjA0NDU4LCJqdGkiOiIzOTk1MmI1NS0yOWQzLTQ4NGQtODhhNC1iMDlhYmI1OWEyNzgiLCJpYXQiOjE1NTYyMDM4NTgsImlzcyI6ImdrLmp3dC5wcm9maWxlU2VydmljZS5hIn0.DFA7KBET3C2q1A9N1hXGMT0QbabHgaVcDBpAYpBdbi8] Accept-Encoding:[gzip, deflate] Connection:[keep-alive] Content-Type:[application/json] User-Agent:[PostmanRuntime/7.11.0] Accept:[*/*] Content-Length:[68]] 0xc0001ba140 <nil> 68 [] false localhost:8080 map[redirect:[/]] map[] <nil> map[] [::1]:36584 /auth/users/login?redirect=/ <nil> <nil> <nil> 0xc00016a2a0}
获取cookie时请求结构如下
// Pretty printed version
Host: localhost:8080
cache-control: no-cache
postman-token: 20f7584f-b59d-46d8-b50f-7040d9d40062
accept-encoding: gzip, deflate
connection: keep-alive
user-agent: PostmanRuntime/7.11.0
accept: */*
// Raw version
2019/04/25 12:22:56 &{GET /path/provide HTTP/1.1 1 1 map[User-Agent:[PostmanRuntime/7.11.0] Accept:[*/*] Cache-Control:[no-cache] Postman-Token:[b79a73a3-3e08-48a4-b350-6bde4ac38d23] Accept-Encoding:[gzip, deflate] Connection:[keep-alive]] {} <nil> 0 [] false localhost:8080 map[] map[] <nil> map[] [::1]:35884 /path/provide <nil> <nil> <nil> 0xc000138240}
当设置cooke
时,响应结构如下response Headers: map[Location:[/] Set-Cookie:[access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwcm9ncmFtVmVyc2lvbiI6IjEuMC4wIiwidXNlckFnZW50IjoiR28taHR0cC1jbGllbnQvMS4xIiwiZXhwIjoxNTU2MjI4ODIyLCJqdGkiOiJlY2Q2NWRkZi1jZjViLTQ4N2YtYTNkYy00NmM3N2IyMmUzMWUiLCJpYXQiOjE1NTYyMjgyMjIsImlzcyI6ImdrLmp3dC5wcm9maWxlU2VydmljZS5hIn0.0sOvEzQS2gczjWSmtVSD_u0qMV2L7M4hKF1KUM08-bQ; Expires=Thu, 25 Apr 2019 21:47:02 GMT; HttpOnly] Date:[Thu, 25 Apr 2019 21:37:02 GMT] Content-Length:[0]]
我希望 Authorize 函数返回 nil。此外,如果我添加以下代码,我希望存在一些 cookie。
for _, cookie := range r.Cookies() {
fmt.Fprint(w, cookie.Name)
}
但是,Authorize 函数返回标题中的错误,并且 printf 没有打印出任何 cookie。
最佳答案
记得设置cookie的路径:
c := &http.Cookie{Name: name, Value: encode(value), Path: "/"}
http.SetCookie(w, c)
如果不这样做,Path 将是当前请求的路径,因此 cookie 将只能从这个确切的路径获得。
关于http - 如何在 golang 中修复 'http: named cookie not present'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55850042/
据我了解,HTTP POST 请求的正文大小没有限制。因此,客户端可能会在一个 HTTP 请求中发送 千兆字节 的数据。现在我想知道 HTTP 服务器应该如何处理此类请求。 Tomcat 和 Jett
在了解Web Deploy我遇到了一些讨论 http://+:80 和 http://*:80 的 netsh.exe 命令。这些是什么意思? 最佳答案 引自URLPrefix Strings (Wi
假设我有一个负载均衡器,然后是 2 个 Web 服务器,然后是一个负载均衡器,然后是 4 个应用程序服务器。 HTTP 响应是否遵循与 HTTP 请求服务相同的路径? 最佳答案 按路径,我假设您是网络
我有一个带有 uri /api/books/122 的资源,如果在客户端为此资源发送 HTTP Delete 时该资源不存在,那么相应的响应代码是什么这个 Action ?是不是404 Not Fou
是否有特定的(或约定的)HTTP 响应消息(或除断开连接之外的其他操作)来阐明服务器不接受 pipelined HTTP requests ? 我正在寻找能让客户端停止流水线化它的请求并分别发送每个请
在了解Web Deploy我遇到了一些讨论 http://+:80 和 http://*:80 的 netsh.exe 命令。这些是什么意思? 最佳答案 引自URLPrefix Strings (Wi
我有一个带有 uri /api/books/122 的资源,如果在客户端为此资源发送 HTTP Delete 时该资源不存在,那么相应的响应代码是什么这个 Action ?是不是404 Not Fou
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
我使用 Mule 作为 REST API AMQP。我必须发送自定义请求方法:“PRINT”,但我收到: Status Code: 400 Bad Request The request could
我需要针对具有不同 HTTP 响应代码的 URL 测试我的脚本。我如何获取响应代码 300、303 或 307 等的示例/示例现有 URL? 谢谢! 最佳答案 您可以使用 httpbin为此目的。 例
我正在尝试编写一个程序来匹配 HTTP 请求及其相应的响应。似乎在大多数情况下一切都运行良好(当传输完全有序时,即使不是,通过使用 TCP 序列号)。 我发现的唯一问题是当我有流水线请求时。在那之后,
RESTful Web Services鼓励使用 HTTP 303将客户端重定向到资源的规范表示。它仅在 HTTP GET 的上下文中讨论主题。 这是否也适用于其他 HTTP 方法?如果客户端尝试对非
当使用chunked HTTP传输编码时,为什么服务器需要同时写出chunk的字节大小并且后续的chunk数据以CRLF结尾? 这不会使发送二进制数据“CRLF-unclean”和方法有点多余吗? 如
这个问题在这里已经有了答案: Is it acceptable for a server to send a HTTP response before the entire request has
如果我向同一台服务器发出多个 HTTP Get 请求并收到每个请求的 HTTP 200 OK 响应,我如何使用 Wireshark 判断哪个请求映射到哪个响应? 目前看起来像是发出了一个 http 请
func main() { http.HandleFunc("/", handler) } func handler(w http.ResponseWriter, r http.Request
我找不到有值(value)的 NodeJS with Typescript 教程,所以我在无指导下潜入水中,果然我有一个问题。 我不明白这两行之间的区别: import * as http from
问一个关于Are HTTP headers case-sensitive?的问题,如果 HTTP 方法区分大小写,大多数服务器如何处理“get”或“post”与“GET”或“POST”? 例如,看起来
我正在使用ASP.NET,在其中我通过动词GET接收查询,该应用程序专用于该URL。 该代码有效,但是如果用户发送的密码使http 200无效,请回答我,并在消息的正文中显示“Fail user or
Closed. This question needs details or clarity。它当前不接受答案。 想改善这个问题吗?添加详细信息,并通过editing this post阐明问题。 9
我是一名优秀的程序员,十分优秀!