Repository: nacos-group/nacos-sdk-go (go)

Issue:
2.x 持久化实例Naming Auth签名走的httpProxy，需要cherry-pick一下1.x的Naming Auth实现
### What version of nacos-sdk-go are you using?
2.1.2

`clients/naming_client/naming_proxy_delegate.go:66`

![image](https://user-images.githubusercontent.com/3050696/200464211-a93b5821-c10b-4941-98e5-33639b7a25b9.png)




Pull request description:
[ISSUE #537] Fix naming http client authentication.
FIX #537 

Patch:
diff --git a/clients/naming_client/naming_http/beat_reactor.go b/clients/naming_client/naming_http/beat_reactor.go
index 366bf55..384446b 100644
--- a/clients/naming_client/naming_http/beat_reactor.go
+++ b/clients/naming_client/naming_http/beat_reactor.go
@@ -144,7 +144,7 @@ func (br *BeatReactor) SendBeat(info *model.BeatInfo) (int64, error) {
 	params["serviceName"] = info.ServiceName
 	params["beat"] = util.ToJsonString(info)
 	api := constant.SERVICE_BASE_PATH + "/instance/beat"
-	result, err := br.nacosServer.ReqApi(api, params, http.MethodPut)
+	result, err := br.nacosServer.ReqApi(api, params, http.MethodPut, br.clientCfg)
 	if err != nil {
 		return 0, err
 	}
diff --git a/clients/naming_client/naming_http/naming_http_proxy.go b/clients/naming_client/naming_http/naming_http_proxy.go
index 0541a7a..93f3927 100644
--- a/clients/naming_client/naming_http/naming_http_proxy.go
+++ b/clients/naming_client/naming_http/naming_http_proxy.go
@@ -77,7 +77,7 @@ func (proxy *NamingHttpProxy) RegisterInstance(serviceName string, groupName str
 	params["healthy"] = strconv.FormatBool(instance.Healthy)
 	params["metadata"] = util.ToJsonString(instance.Metadata)
 	params["ephemeral"] = strconv.FormatBool(instance.Ephemeral)
-	_, err := proxy.nacosServer.ReqApi(constant.SERVICE_PATH, params, http.MethodPost)
+	_, err := proxy.nacosServer.ReqApi(constant.SERVICE_PATH, params, http.MethodPost, proxy.clientConfig)
 	if err != nil {
 		return false, err
 	}
@@ -110,7 +110,7 @@ func (proxy *NamingHttpProxy) DeregisterInstance(serviceName string, groupName s
 	params["ip"] = instance.Ip
 	params["port"] = strconv.Itoa(int(instance.Port))
 	params["ephemeral"] = strconv.FormatBool(instance.Ephemeral)
-	_, err := proxy.nacosServer.ReqApi(constant.SERVICE_PATH, params, http.MethodDelete)
+	_, err := proxy.nacosServer.ReqApi(constant.SERVICE_PATH, params, http.MethodDelete, proxy.clientConfig)
 	if err != nil {
 		return false, err
 	}
@@ -138,7 +138,7 @@ func (proxy *NamingHttpProxy) GetServiceList(pageNo uint32, pageSize uint32, gro
 	serviceList := model.ServiceList{}
 
 	api := constant.SERVICE_BASE_PATH + "/service/list"
-	result, err := proxy.nacosServer.ReqApi(api, params, http.MethodGet)
+	result, err := proxy.nacosServer.ReqApi(api, params, http.MethodGet, proxy.clientConfig)
 	if err != nil {
 		return serviceList, err
 	}
@@ -165,7 +165,7 @@ func (proxy *NamingHttpProxy) GetServiceList(pageNo uint32, pageSize uint32, gro
 // ServerHealthy ...
 func (proxy *NamingHttpProxy) ServerHealthy() bool {
 	api := constant.SERVICE_BASE_PATH + "/operator/metrics"
-	result, err := proxy.nacosServer.ReqApi(api, map[string]string{}, http.MethodGet)
+	result, err := proxy.nacosServer.ReqApi(api, map[string]string{}, http.MethodGet, proxy.clientConfig)
 	if err != nil {
 		logger.Errorf("namespaceId:[%s] sending server healthy failed!,result:%s error:%+v", proxy.clientConfig.NamespaceId, result, err)
 		return false
@@ -192,7 +192,7 @@ func (proxy *NamingHttpProxy) QueryInstancesOfService(serviceName, groupName, cl
 	param["healthyOnly"] = strconv.FormatBool(healthyOnly)
 	param["clientIP"] = util.LocalIP()
 	api := constant.SERVICE_PATH + "/list"
-	result, err := proxy.nacosServer.ReqApi(api, param, http.MethodGet)
+	result, err := proxy.nacosServer.ReqApi(api, param, http.MethodGet, proxy.clientConfig)
 	if err != nil {
 		return nil, err
 	}
diff --git a/common/nacos_server/nacos_server.go b/common/nacos_server/nacos_server.go
index b9e1fbd..1ef3528 100644
--- a/common/nacos_server/nacos_server.go
+++ b/common/nacos_server/nacos_server.go
@@ -226,13 +226,14 @@ func (server *NacosServer) ReqConfigApi(api string, params map[string]string, he
 	return "", errors.Wrapf(err, "retry %d times request failed!", constant.REQUEST_DOMAIN_RETRY_TIME)
 }
 
-func (server *NacosServer) ReqApi(api string, params map[string]string, method string) (string, error) {
+func (server *NacosServer) ReqApi(api string, params map[string]string, method string, config constant.ClientConfig) (string, error) {
 	srvs := server.serverList
 	if srvs == nil || len(srvs) == 0 {
 		return "", errors.New("server list is empty")
 	}
 
 	server.InjectSecurityInfo(params)
+	server.InjectSignForNamingHttp(params, config)
 
 	//only one server,retry request when error
 	var err error
@@ -336,6 +337,26 @@ func (server *NacosServer) InjectSecurityInfo(param map[string]string) {
 	}
 }
 
+func (server *NacosServer) InjectSignForNamingHttp(param map[string]string, clientConfig constant.ClientConfig) {
+	if clientConfig.AccessKey == "" || clientConfig.SecretKey == "" {
+		return
+	}
+	var signData string
+	timeStamp := strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
+	if serviceName, hasServiceName := param["serviceName"]; hasServiceName {
+		if groupName, hasGroup := param["groupName"]; strings.Contains(serviceName, constant.SERVICE_INFO_SPLITER) || !hasGroup || groupName == "" {
+			signData = timeStamp + constant.SERVICE_INFO_SPLITER + serviceName
+		} else {
+			signData = timeStamp + constant.SERVICE_INFO_SPLITER + util.GetGroupName(serviceName, groupName)
+		}
+	} else {
+		signData = timeStamp
+	}
+	param["signature"] = signWithhmacSHA1Encrypt(signData, clientConfig.SecretKey)
+	param["ak"] = clientConfig.AccessKey
+	param["data"] = signData
+}
+
 func (server *NacosServer) InjectSign(request rpc_request.IRequest, param map[string]string, clientConfig constant.ClientConfig) {
 	if clientConfig.AccessKey == "" || clientConfig.SecretKey == "" {
 		return


Test patch:
diff --git a/common/nacos_server/nacos_server_test.go b/common/nacos_server/nacos_server_test.go
index 6ca6fc7..19130e2 100644
--- a/common/nacos_server/nacos_server_test.go
+++ b/common/nacos_server/nacos_server_test.go
@@ -17,6 +17,8 @@
 package nacos_server
 
 import (
+	"context"
+	"github.com/nacos-group/nacos-sdk-go/v2/common/http_agent"
 	"testing"
 
 	"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
@@ -46,3 +48,110 @@ func Test_getAddressWithoutScheme(t *testing.T) {
 	assert.Equal(t, "https://console.nacos.io:80", getAddress(serverConfigTest))
 
 }
+
+func buildNacosServer(clientConfig constant.ClientConfig) (*NacosServer, error) {
+	return NewNacosServer(context.Background(),
+		[]constant.ServerConfig{*constant.NewServerConfig("http://console.nacos.io", 80)},
+		clientConfig,
+		&http_agent.HttpAgent{},
+		1000,
+		"")
+}
+
+func TestNacosServer_InjectSignForNamingHttp_NoAk(t *testing.T) {
+	clientConfig := constant.ClientConfig{
+		AccessKey: "123",
+		SecretKey: "321",
+	}
+	server, err := buildNacosServer(clientConfig)
+	if err != nil {
+		t.FailNow()
+	}
+
+	param := make(map[string]string)
+	param["serviceName"] = "s-0"
+	param["groupName"] = "g-0"
+	server.InjectSignForNamingHttp(param, constant.ClientConfig{})
+	assert.Empty(t, param["ak"])
+	assert.Empty(t, param["data"])
+	assert.Empty(t, param["signature"])
+}
+
+func TestNacosServer_InjectSignForNamingHttp_WithGroup(t *testing.T) {
+	clientConfig := constant.ClientConfig{
+		AccessKey: "123",
+		SecretKey: "321",
+	}
+	server, err := buildNacosServer(clientConfig)
+	if err != nil {
+		t.FailNow()
+	}
+
+	param := make(map[string]string)
+	param["serviceName"] = "s-0"
+	param["groupName"] = "g-0"
+	server.InjectSignForNamingHttp(param, clientConfig)
+	assert.Equal(t, "123", param["ak"])
+	assert.Contains(t, param["data"], "@@g-0@@s-0")
+	_, has := param["signature"]
+	assert.True(t, has)
+}
+
+func TestNacosServer_InjectSignForNamingHttp_WithoutGroup(t *testing.T) {
+	clientConfig := constant.ClientConfig{
+		AccessKey: "123",
+		SecretKey: "321",
+	}
+	server, err := buildNacosServer(clientConfig)
+	if err != nil {
+		t.FailNow()
+	}
+
+	param := make(map[string]string)
+	param["serviceName"] = "s-0"
+	server.InjectSignForNamingHttp(param, clientConfig)
+	assert.Equal(t, "123", param["ak"])
+	assert.NotContains(t, param["data"], "@@g-0@@s-0")
+	assert.Contains(t, param["data"], "@@s-0")
+	_, has := param["signature"]
+	assert.True(t, has)
+}
+
+func TestNacosServer_InjectSignForNamingHttp_WithoutServiceName(t *testing.T) {
+	clientConfig := constant.ClientConfig{
+		AccessKey: "123",
+		SecretKey: "321",
+	}
+	server, err := buildNacosServer(clientConfig)
+	if err != nil {
+		t.FailNow()
+	}
+
+	param := make(map[string]string)
+	param["groupName"] = "g-0"
+	server.InjectSignForNamingHttp(param, clientConfig)
+	assert.Equal(t, "123", param["ak"])
+	assert.NotContains(t, param["data"], "@@")
+	assert.Regexp(t, "\\d+", param["data"])
+	_, has := param["signature"]
+	assert.True(t, has)
+}
+
+func TestNacosServer_InjectSignForNamingHttp_WithoutServiceNameAndGroup(t *testing.T) {
+	clientConfig := constant.ClientConfig{
+		AccessKey: "123",
+		SecretKey: "321",
+	}
+	server, err := buildNacosServer(clientConfig)
+	if err != nil {
+		t.FailNow()
+	}
+
+	param := make(map[string]string)
+	server.InjectSignForNamingHttp(param, clientConfig)
+	assert.Equal(t, "123", param["ak"])
+	assert.NotContains(t, param["data"], "@@")
+	assert.Regexp(t, "\\d+", param["data"])
+	_, has := param["signature"]
+	assert.True(t, has)
+}