alibaba / nacos

an easy-to-use dynamic service discovery, configuration and service management platform for building cloud native applications.
https://nacos.io
Apache License 2.0
30.07k stars 12.81k forks source link

nacos client /v1/auth/users/login error #4020

Closed steveoyung closed 3 years ago

steveoyung commented 3 years ago

evironment: nacos server: 1.3.2 nacos client: 1.3.2 springcloud alibaba 2.2.2-release

description: config: server-addr: @spring.application.cloud.nacos.config.server-addr@ file-extension: yml refresh: true shared-dataids: @spring.application.cloud.nacos.config.shared-dataids@ namespace: @spring.application.cloud.nacos.config.namespace@ username: @spring.application.cloud.nacos.config.username@ password: '@spring.application.cloud.nacos.config.password@' discovery: server-addr: @spring.application.cloud.nacos.discovery.server-addr@ namespace: @spring.application.cloud.nacos.discovery.namespace@ username: @spring.application.cloud.nacos.discovery.username@ password: '@spring.application.cloud.nacos.discovery.password@'

I got the error: SecurityProxy: v1/auth/users/login, params: {username=nacos}, bodyMap: {password=2333232322}, errorMsg: errCode: 100, errMsg: Nacos serialize for class [com.alibaba.nacos.common.http.HttpRestResult] failed.

config service incorrect. it works ok when delete blocks username/password。

discovery service works ok

steveoyung commented 3 years ago

maybe There will be a bug. public boolean login(String server) throws UnsupportedEncodingException { if (StringUtils.isNotBlank(this.username)) { Map<String, String> params = new HashMap(2); Map<String, String> bodyMap = new HashMap(2); params.put("username", this.username); bodyMap.put("password", URLEncoder.encode(this.password, "utf-8")); String url = "http://" + server + this.contextPath + "/v1/auth/users/login"; if (server.contains("http")) { url = server + this.contextPath + "/v1/auth/users/login"; }

        try {
            HttpRestResult<String> restResult = this.nacosRestTemplate.postForm(url, Header.EMPTY, Query.newInstance().initParams(params), bodyMap, String.class);
            if (!restResult.ok()) {
                SECURITY_LOGGER.error("login failed: {}", JacksonUtils.toJson(restResult));
                return false;
            }

            JsonNode obj = JacksonUtils.toObj((String)restResult.getData());
            if (obj.has("accessToken")) {
                this.accessToken = obj.get("accessToken").asText();
                this.tokenTtl = (long)obj.get("tokenTtl").asInt();
                this.tokenRefreshWindow = this.tokenTtl / 10L;
            }
        } catch (Exception var7) {
            SECURITY_LOGGER.error("[SecurityProxy] login http request failed url: {}, params: {}, bodyMap: {}, errorMsg: {}", new Object[]{url, params, bodyMap, var7.getMessage()});
            return false;
        }
    }

    return true;
}
steveoyung commented 3 years ago

If password contains characters like @ etc, [ bodyMap.put("password", URLEncoder.encode(this.password, "utf-8")); ] makes password error, so just remove characters like @。

KomachiSion commented 3 years ago

will be fixed in 1.4.0

duplicate with #3992

KomachiSion commented 3 years ago

@steveoyung I find your error seems is serialization error , can you provide full error information?

steveoyung commented 3 years ago

@steveoyung I find your error seems is serialization error , can you provide full error information?

@KomachiSion that's all error log. I found the root cause: password contains character '@', it does not match with the server api when urlencoding password (URLEncoder.encode(this.password, "utf-8"))

KomachiSion commented 3 years ago

I know the caused reason and will be fixed in 1.4.0, detail see #3992 .

But when I test, the error is unknown user, not is serialization error.

So I want to know the response or what cause the serialization error.

Can you debug and get the response and provide in comment? Thanks

KomachiSion commented 3 years ago

Serialization error will be fixed in 1.4.0, #3721