-
Notifications
You must be signed in to change notification settings - Fork 638
Add token support for API calls #84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Hello, thanks for the patch! I'm on vacation currently, I'll have a look when I'm back. The changes themselves look good, I'll just have to think through the order of precedence between the various authentication values. |
|
@karmi Did the precedence match what you expected? |
|
Hi, sorry for such a long delay! I've been thinking about the feature a little bit more, and I've realized it would actually make the client diverge from the other official clients, which don't support such a feature out of the box. Since Elasticsearch itself doesn't support a token-based authentication, and it's applicable only when some kind of proxy sits in front of it, I think it qualifies as a "custom environment". Therefore, I'd suggest creating a custom transport, wrapping the default one, and setting the request header — as in the following example: //+build ignore
package main
import (
"fmt"
"log"
"net/http"
"os"
"github.com/elastic/go-elasticsearch/v8"
"github.com/elastic/go-elasticsearch/v8/estransport"
)
const (
serverToken = "abc123"
clientToken = "xyz456" // <<< Change to the same value for successful authorization
)
type AuthorizedTransport struct{}
func (t *AuthorizedTransport) RoundTrip(req *http.Request) (*http.Response, error) {
req.Header.Set("Authorization", "Bearer "+clientToken)
fmt.Println(">>> ", req.Header.Get("Authorization"))
return http.DefaultTransport.RoundTrip(req)
}
func main() {
log.SetFlags(0)
defaultHandler := func(w http.ResponseWriter, r *http.Request) {
fmt.Println("<<< ", r.Header.Get("Authorization"))
if r.Header.Get("Authorization") != "Bearer "+serverToken {
http.Error(w, "Invalid credentials", 403)
return
}
fmt.Fprintln(w, "OK")
}
go func() {
log.Fatalln(http.ListenAndServe("localhost:10100", http.HandlerFunc(defaultHandler)))
}()
es, _ := elasticsearch.NewClient(
elasticsearch.Config{
Addresses: []string{"http://localhost:10100"},
Transport: &AuthorizedTransport{},
// >>>>> Wrap the transport >>>>>>>>>>>>>>>>>>>>>>>>
Logger: &estransport.ColorLogger{Output: os.Stdout},
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
})
res, err := es.Info()
if err != nil {
log.Fatalf("Error getting response: %v", err)
}
defer res.Body.Close()
if res.IsError() {
log.Fatalf("Error response: %s", res)
}
log.Println(res)
}With this reasoning, I'd like to close the PR without merging. Please re-open or comment if you would like to discuss it further. |
|
Hi @geoffmore , I was wrong about Elasticsearch itself not supporting the bearer/token authentication — sorry about that. There's a broader discussion happening in #106 (comment) now about custom HTTP headers, which is related to the bearer/token authentication feature. |
hdr := http.Header{}
hdr.Set("Accept", "application/yaml")
hdr.Set("Authorization", "Bearer 46ToAxZ2ZGZCaDhEVVNJQ0J1dUYzdGZxa1BB")
es, err := elasticsearch.NewClient(
elasticsearch.Config{
Header: hdr,
},
)
res, _ := es.Info()
fmt.Println(res)
# [200 OK] ---
# name: "es1"
# ...
Related:
* #136
* #84
* #106 (comment)
hdr := http.Header{}
hdr.Set("Accept", "application/yaml")
hdr.Set("Authorization", "Bearer 46ToAxZ2ZGZCaDhEVVNJQ0J1dUYzdGZxa1BB")
es, err := elasticsearch.NewClient(
elasticsearch.Config{
Header: hdr,
},
)
res, _ := es.Info()
fmt.Println(res)
# [200 OK] ---
# name: "es1"
# ...
Related:
* #136
* #84
* #106 (comment)
(cherry picked from commit 3f39d54)
hdr := http.Header{}
hdr.Set("Accept", "application/yaml")
hdr.Set("Authorization", "Bearer 46ToAxZ2ZGZCaDhEVVNJQ0J1dUYzdGZxa1BB")
es, err := elasticsearch.NewClient(
elasticsearch.Config{
Header: hdr,
},
)
res, _ := es.Info()
fmt.Println(res)
# [200 OK] ---
# name: "es1"
# ...
Related:
* #136
* #84
* #106 (comment)
(cherry picked from commit 3f39d54)
hdr := http.Header{}
hdr.Set("Accept", "application/yaml")
hdr.Set("Authorization", "Bearer 46ToAxZ2ZGZCaDhEVVNJQ0J1dUYzdGZxa1BB")
es, err := elasticsearch.NewClient(
elasticsearch.Config{
Header: hdr,
},
)
res, _ := es.Info()
fmt.Println(res)
# [200 OK] ---
# name: "es1"
# ...
Related:
* #136
* #84
* #106 (comment)
(cherry picked from commit 3f39d54)
|
Custom global HTTP request headers have been added in 3f39d54. |
The context behind this PR is my desire to support token based authentication for API calls.
The following changes were made to support token authentication according to token documentation.
elasticsearch.go:
estransport/estransport.go
func (c *Client) setAuthorization(u *url.URL, req *http.Request) *http.Request, add logic supporting token headers similar what is done for apikey.