Go 403制作戈朗柱时禁止使用

Go 403制作戈朗柱时禁止使用,go,http-status-code-403,Go,Http Status Code 403,我有一个由JavaSpring启动应用程序提供的REST端点,我正试图用一个简单的Go(go1.8Darwin/amd64)程序来实现它。我尝试了两种不同的方式: const ( LOCAL_BASE = "http://localhost:11400" ADD_FUNDS_ENDPOINT = "/sub-accounts/%d/add-funds" ) type InputArgumentsJson struct { Amount

我有一个由JavaSpring启动应用程序提供的REST端点,我正试图用一个简单的Go(go1.8Darwin/amd64)程序来实现它。我尝试了两种不同的方式:

const (
    LOCAL_BASE         = "http://localhost:11400"
    ADD_FUNDS_ENDPOINT = "/sub-accounts/%d/add-funds"
)

type InputArgumentsJson struct {
    Amount           float64 `json:"amount"`
    BufferAmount     float64 `json:"bufferAmount"`
    FromSubAccountID int     `json:"fromSubAccountId"`
}

...

// set up json body
inputArguments := &InputArgumentsJson{Amount: 1100, BufferAmount: 0,
    FromSubAccountID: spendFundId}
bytes := new(bytes.Buffer)
json.NewEncoder(bytes).Encode(inputArguments)

// set up the url to call
endpoint := fmt.Sprintf(ADD_FUNDS_ENDPOINT, billSetAsideId)
url := LOCAL_BASE + endpoint

client := &http.Client{}

req, err := http.NewRequest("POST", url, bytes)
if err != nil {
    fmt.Println("ERROR WHILE BUILDING REQUEST")
    fmt.Println(err)
}

req.Header.Add("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
    fmt.Println("ERROR WHILE MAKING REQUEST")
    fmt.Println(err)
}
fmt.Println(resp)
以及:

我添加了一份打印件,以查看URL和JSON正文是否正确,它们似乎是:

fmt.Printf("\nMaking request to %s with:\n %s\n", url, bytes)
打印出来

Making request to http://localhost:11400/sub-accounts/167/add-funds with:
{"amount":1100,"bufferAmount":0,"fromSubAccountId":166}
但我在运行它时得到了403

我可以使用Postman和以下Curl命令毫无疑问地命中该端点:

curl-H“Content-Type:application/json”-X POST-d'{“amount”:1100,“bufferAmount”:0,“fromsubaccounted”:166}”http://localhost:11400/sub-账户/167/添加资金

有人对我在这里遗漏的东西有什么想法吗?为了更进一步,我可以成功地从Go程序中找到一个不同的GET端点

提前谢谢


编辑以显示我捕获了错误以及创建URL和JSON正文的周围逻辑

您没有显示
字节
是什么,但这很可能是问题所在:无论是
NewRequest
还是
Post
都使用
io.Reader
并从该阅读器读取正文。这种读取通常只能发生一次(想想流)。当您
fmt.Printf(“%s”)
io.Reader时,此打印将使用内容(很可能是通过调用String()方法),实际请求是在一个空正文中完成的


始终显示整个代码。不要尝试从io.Reader读取两次。

我假设有两个Go应用程序在不同的主机上运行,这会导致出现问题。考虑添加<代码>访问控制,允许源代码< /代码>在您的客户端主机上服务。< /P>
w.Header().Set(“访问控制允许原点”,“*”)


您可以使用客户端应用程序运行的指定主机名更改
*

OMG…我刚刚发现了问题。结果证明它失败了(正如我所预料的),但它错误地返回了403而不是400。呃……有时候,当你长时间盯着某个东西看时,明显的事情完全不会引起注意。

你应该在请求头中设置用户代理

req, _ := http.NewRequest(http.MethodGet, urlString, nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36")

首先尝试捕获您的请求和响应中的错误,
resp,err:=client.Do(req)
。实际上,我是这样捕获它们的,然后让
if err!=nil
打印出来,但什么都不会被捕获。为了简洁起见,我把它省略了,因为服务器显然正在响应,但是有一个403。这是一个好主意,但不管我是否打印字节,它都会响应。我编辑了我的代码以显示所有内容。服务器实际上是一个JavaSpring启动应用程序。奇怪的是,当它在本地主机上或将Spring Boot应用程序部署到AWS上时,我得到了相同的结果。在这两种情况下,本地运行的Go应用程序都会得到403,而Curl和Postman可以成功地命中端点,而不管它从何处运行。CORS问题不会出现在GET请求和POST请求中吗?我可以用我的Go程序成功地完成GET,而不是POST。你能用Go和Curl记录请求/响应头吗?这不是CORS问题,但你的回答让我更仔细地查看发现问题的服务器。我的Go应用程序一直都很好,但是Java应用程序有点不稳定。
req, _ := http.NewRequest(http.MethodGet, urlString, nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36")