我正在尝试实现Rest API登录过程。我已经用curl
验证了该过程。
使用curl
,以下命令将进行登录:
$ curl -i -X POST https://the-service.mycompany.com/login -d username=<my username> -d password=<mypassword>
HTTP/1.1 200 Connection established
HTTP/1.1 302
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT, PATCH
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: x-requested-with, content-type, authorization, X-RateLimit-App, X-Spinnaker-Priority
Access-Control-Expose-Headers: X-AUTH-REDIRECT-URL
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Set-Cookie: SESSION=ODdmNGZjZmEtY2EwOC00YzA4LWFmMmYtMjAwNDI1ODM2NjI3; Path=/; HttpOnly; SameSite=Lax
Location: http://the-service.mycompany.com
Content-Length: 0
Date: Thu, 18 Jul 2019 14:38:40 GMT
此命令将成功执行并返回cookie作为响应。
但是当我尝试使用Go代码时:
http := http.Client{
}
const body = "username=myuser&password=mypass"
req, err := http.NewRequest("POST", "https://the-service.mycompany.com/login", strings.NewReader(body))
req.Header.Add("Accept", "*/*")
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Del("Accept-Encoding")
dump, err := httputil.DumpRequestOut(req, true)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%q\n", dump)
resp, err := client.Do(req)
dump, err = httputil.DumpRequestOut(resp.Request, true)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%q\n", dump)
fmt.Println("Dump response ==================")
fmt.Println(resp.Status)
for k, v := range resp.Header {
fmt.Printf("%s: %s\n", k, v)
}
它返回的响应与curl
得到的响应不同,这意味着响应头和主体完全不同。
我注意到curl
返回两个状态代码200和302。但是go
代码的resp.Status
是200。
go
代码输出为:
"POST /login HTTP/1.1\r\nHost: the-service.mycompany.com\r\nUser-Agent: Go-http-client/1.1\r\nContent-Length: 36\r\nAccept: */*\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept-Encoding: gzip\r\n\r\nusername=myuser&password=mypass"
"GET /login HTTP/1.1\r\nHost: the-service.mycompany.com\r\nUser- Agent: Go-http-client/1.1\r\nAccept: */*\r\nContent-Type: application/x-www-form-urlencoded\r\nReferer: http://the-service.mycompany.com/login\r\nAccept-Encoding: gzip\r\n\r\n"
Dump response ==================
200
Access-Control-Allow-Origin: [*]
Access-Control-Max-Age: [3600]
Cache-Control: [no-cache, no-store, max-age=0, must-revalidate]
Date: [Thu, 18 Jul 2019 14:53:07 GMT]
Access-Control-Allow-Credentials: [true]
Content-Type: [text/html;charset=UTF-8]
X-Xss-Protection: [1; mode=block]
Pragma: [no-cache]
X-Frame-Options: [DENY]
X-Content-Type-Options: [nosniff]
Access-Control-Allow-Headers: [x-requested-with, content-type, authorization, X-RateLimit-App, X-Spinnaker-Priority]
Access-Control-Expose-Headers: [X-AUTH-REDIRECT-URL]
Expires: [0]
Content-Length: [1324]
Access-Control-Allow-Methods: [POST, GET, OPTIONS, DELETE, PUT, PATCH]
从输出开始,在发送之前,请求是POST,但是当我转储resp.Request
时,请求变成了GET
,为什么?
答案 0 :(得分:2)
最后,我找出了问题所在。让我做一个自我回答,希望它对将来遇到类似问题的人有所帮助。
实际上,就我而言,curl
不会自动重定向,因为我没有将-L
选项与curl
一起使用。但是go POST可以自动重定向。
所以我添加了一个CheckRedirect
函数来阻止重定向:
func check(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}
... in main() ...
client := http.Client {
CheckRedirect: check,
}
然后client.PostForm
返回与curl
得到的结果相同的302结果。