Skip to content

长链接转短链接接口的小BUG #1087

@sinrimin

Description

@sinrimin

准确来说应该是微信接口的BUG,但可能会在一定条件下瞬间刷爆access_token。

简要描述

长链接转短链接接口中的 long_url 如果带有名为 access_token 的参数,会直接导致接口返回 40001,如果项目的 autoRefreshToken 也正好是 true ,会直接导致 java.lang.StackOverflowError 并刷爆服务号的 access_token

模块版本情况

  • WxJava 模块名: weixin-java-mp
  • WxJava 版本号:3.3.0

期待结果 和 实际情况

先说说微信的BUG

使用官方例子调用长链接转短链接( long_url 添加 access_token 参数):

 curl -d "{\"action\":\"long2short\",\"long_url\":\"http://wap.koudaitong.com/v2/showcase/goods?alias=128wi9shh&spm=h56083&redirect_count=1&access_token={random_str}\"}" "https://api.weixin.qq.com/cgi-bin/shorturl?access_token={access_token}"
  • {random_str} : 随机字符串,网址中的参数名正好被命名成了access_token
  • {access_token} : 正常可用的微信access_token

返回值

{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest hint: [1l1fVa08158619!]"}

修改上面long_url中 access_token 的参数名,或者去掉 access_token 这个参数(这里改成了 bccess_token

 curl -d "{\"action\":\"long2short\",\"long_url\":\"http://wap.koudaitong.com/v2/showcase/goods?alias=128wi9shh&spm=h56083&redirect_count=1&bccess_token={random_str}\"}" "https://api.weixin.qq.com/cgi-bin/shorturl?access_token={access_token}"
  • {random_str} : 同上
  • {access_token} : 同上

返回值

{"errcode":0,"errmsg":"ok","short_url":"https:\/\/w.url.cn\/s\/AdCvL5R"}

再看看项目中的代码

me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl

  ...
  public <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
      ...
      if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) {
        this.getWxMpConfigStorage().expireAccessToken();
        if (this.getWxMpConfigStorage().autoRefreshToken()) {
          return this.execute(executor, uri, data);
        }
      }
  ...

代码中判断到 40001 会让当前 access_token 失效,并且判断到 autoRefreshToken 会继续调用 this.execute()方法

  public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
  ...
      try {
        return this.executeInternal(executor, uri, data);
      } catch (WxErrorException e) {
  ...

也就是回到上一个方法,但同样会返回 40001,开始死循环。

日志

Handler dispatch failed; nested exception is java.lang.StackOverflowError
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.StackOverflowError
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:982)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Caused by: java.lang.StackOverflowError: null
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
	at java.net.SocketInputStream.read(SocketInputStream.java:171)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
	at sun.security.ssl.InputRecord.read(InputRecord.java:503)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
	at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:930)
	at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
	at okio.Okio$2.read(Okio.java:139)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions