{"record":{"id":"5814ee847b82609c","repo":"justauth/JustAuth","slug":"token","errorCode":null,"errorMessage":"企业微信获取token失败","messagePattern":"企业微信获取token失败","errorType":"exception","errorClass":"AuthException","httpStatus":null,"severity":"error","filePath":"src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseThirdQrcodeRequest.java","lineNumber":70,"sourceCode":"        } catch (Exception e) {\n            Log.error(\"Failed to login with oauth authorization.\", e);\n            return this.responseError(e);\n        }\n    }\n\n    @Override\n    public AuthToken getAccessToken(AuthCallback authCallback) {\n        try {\n            String response = doGetAuthorizationCode(accessTokenUrl());\n            JSONObject object = this.checkResponse(response);\n            AuthToken authToken = AuthToken.builder()\n                .accessToken(object.getString(\"provider_access_token\"))\n                .expireIn(object.getIntValue(\"expires_in\"))\n                .code(authCallback.getCode())\n                .build();\n            return authToken;\n        } catch (Exception e) {\n            throw new AuthException(\"企业微信获取token失败\", e);\n        }\n    }\n\n    @Override\n    protected String doGetAuthorizationCode(String code) {\n        JSONObject data = new JSONObject();\n        data.put(\"corpid\", config.getClientId());\n        data.put(\"provider_secret\", config.getClientSecret());\n        return new HttpUtils(config.getHttpConfig()).post(accessTokenUrl(code), data.toJSONString()).getBody();\n    }\n\n    /**\n     * 获取token的URL\n     *\n     * @return accessTokenUrl\n     */\n    protected String accessTokenUrl() {\n        return UrlBuilder.fromBaseUrl(source.accessToken())","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/justauth/JustAuth/blob/694bbf1b010d93404e3bfb4824d90e9ddfaebebb/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseThirdQrcodeRequest.java#L52-L88","documentation":"AuthWeChatEnterpriseThirdQrcodeRequest.getAccessToken wraps the whole provider-token flow in try/catch and rethrows AuthException(\"企业微信获取token失败\", e) — Chinese message 'WeChat Work failed to get token' — with the original exception as cause. It fires when fetching the provider_access_token via POST /cgi-bin/service/get_provider_token with corpid + provider_secret, for third-party (服务商) QR login.","triggerScenarios":"Any exception during getProviderToken: HTTP failure (network/DNS/timeout), non-JSON response, or the nested checkResponse throwing because the WeChat server returned errcode != 0 (e.g. 40001 invalid credential, 40056 invalid corpid/provider_secret).","commonSituations":"provider_secret of the service provider mismatched or rotated; corpid (clientId) wrong — using the corp's id instead of the provider's; server IP not in the trusted/IP-whitelist config of WeChat Work; egress firewall blocking qyapi.weixin.qq.com.","solutions":["Inspect the nested cause (`e.getCause()`) — the real reason (errcode/errmsg from WeChat or an IOException) is inside the wrapper.","Verify clientId = provider's corpid and clientSecret = provider_secret from the 服务商 console, not the target enterprise's credentials.","Add your server's egress IP to the provider's IP whitelist and verify connectivity to https://qyapi.weixin.qq.com.","If cause shows errcode 40001/42001, the provider token logic is fine but credentials/whitelist are wrong — fix config, not code."],"exampleFix":"// surfacing the real cause for diagnosis\ntry {\n    AuthToken t = request.getAccessToken(callback);\n} catch (AuthException e) {\n    Throwable root = e.getCause();\n    log.error(\"provider token failed: {}\", root == null ? e.getMessage() : root.getMessage(), root);\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight connectivity + credentials presence\nif (StringUtils.isAnyEmpty(config.getClientId(), config.getClientSecret())) {\n    throw new IllegalArgumentException(\"WeChat Work third-party: corpid/provider_secret required\");\n}\n// optional: cheap reachability probe\n// new HttpUtils(config.getHttpConfig()).get(\"https://qyapi.weixin.qq.com/cgi-bin/gettoken\") ...","typeGuard":null,"tryCatchPattern":"try {\n    AuthToken t = request.getAccessToken(callback);\n} catch (AuthException e) {\n    Throwable cause = e.getCause();\n    log.error(\"provider token failure, root: {}\", cause == null ? \"none\" : cause.getMessage(), e);\n    if (cause instanceof AuthException) {\n        String m = String.valueOf(cause.getMessage());\n        if (m.contains(\"40001\") || m.contains(\"invalid\")) refreshProviderTokenAndRetry();\n    }\n}","preventionTips":["Always log the cause chain — the wrapper message is generic by design.","Whitelist server egress IPs in the WeChat Work provider console.","Cache provider_access_token for its full TTL (~2h) to avoid hitting rate limits."],"tags":["justauth","wechat-work","third-party-provider","token","wrapped-exception"],"backgroundTag":null,"analyzedSha":"694bbf1b010d93404e3bfb4824d90e9ddfaebebb","analyzedAt":"2026-08-14T15:16:59.945Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}