Reputation: 759
In my Go application I use a Web API, which accepts a POST request and returns a token if it is successful.
The URL is the following: "https://accounts.zoho.com/apiauthtoken/nb/create?SCOPE=xxxx&EMAIL_ID=xxxx&PASSWORD=xxxx"
If I send this in Postman or any other tool, I get the status code 200 with the expected body, but in my go code the same request returns error code 400.
url := "https://accounts.zoho.com/apiauthtoken/nb/create?SCOPE=xxxx&EMAIL_ID=xxxx&PASSWORD=xxxx"
req, err := http.NewRequest("POST", url, nil)
log.Println(err)
res, err := client.Do(req)
log.Println(err)
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
log.Println(err)
fmt.Println(res)
fmt.Println(string(body))
All errors are nil, but the res struct contains 400 Bad Request and the last output (of the body) is empty.
&{400 Bad Request 400 HTTP/1.1 1 1 map[Date:[Sat, 03 Mar 2018 16:48:35 GMT] Connection:[keep-alive] Set-Cookie:[a8c61fa0dc=5f224f2ab9d067cfce10fd0b7fae48bf; Path=/; Secure; HttpOnly] Server:[ZGS]] 0xc04225a080 -1 [chunked] false false map[] 0xc042034a00 0xc0421bc370}
I would appreciate any help, because I don't know where this problem comes from.
Upvotes: 1
Views: 3469
Reputation: 493
Same question here, try to make a POST request with some QUERY params in url, which works fine in Postman but always got Http 400 in go debug with all the same params (Query params , post body ,headers and MD5 sign)
timeStr := time.Now().Format("2006-01-02 15:04:05")
serverUrlAll = serverUrlAll + "?token="+token+"&provider="+provide+"×tamp="+timeStr+"&signature="+signature
contentBody := strings.NewReader(signString)
request, err := http.NewRequest("POST",serverUrlAll , contentBody)
if err != nil {
return nil, err
}
request.Header.Set("Content-Type", "application/json")
Finally found the blank in query url will cause the error , remove the blank and it works in my case.
Upvotes: 0
Reputation: 1
I was facing the similar issue. The reason for 401
simply means the invalid authorization token. Later I noticed that Postman executes the Pre-request script
that updates the header every time. You can pull in the same pre-request script code in golang and it works.
Upvotes: 0
Reputation: 12675
Url-encoded parameters should be provided in body parameter not as query string. So this can be a problem too. Set your paramters in body implementing io.Reader
.
func NewRequest(method, url string, body io.Reader) (*Request, error)
Set the header Content-Type in your request before sending it using Client.Do
.
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
Since postman is smart enough to set the headers for you. Thats why no error. The whole code becomes
package main
import (
"log"
"net/http"
"net/url"
"io/ioutil"
"strings"
)
func main(){
url := "https://accounts.zoho.com/apiauthtoken/nb/create"
var data url.Values{}
data.Set("SCOPE","xxxx")
data.Add("EMAIL","xxxx")
data.Add("PASSWORD","xxxx")
req, err := http.NewRequest("POST", url, strings.NewReader(data.Encode()))
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
log.Println(err)
res, err := client.Do(req)
log.Println(err)
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
log.Println(err)
fmt.Println(res)
fmt.Println(string(body))
}
Upvotes: 1