V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
tinyproxy
V2EX  ›  问与答

微信 oAuth 抽风

  •  
  •   tinyproxy · 2016-03-04 13:15:11 +08:00 · 2460 次点击
    这是一个创建于 3215 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Hi, V2EX 上面有没有微信的开发人员?

    1. 我们的服务接入了微信的 oAuth ,但是微信的 oAuth 结果经常抽风,有时授权正常,有时授权抽风。

    2. 文档在这里 http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html

    3. 文档

    3.1 先构造一个 URL 让用户在微信内访问微信服务器,比如是这样子的 https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

    3.2 访问成功后就是用户点就同意授权啦,之后会在 callback URL 里面带上一个 code 给我们的业务服务器

    3.3 业务服务器根据这个 code 找微信服务器要用户信息

    3.4 其他就是我们业务服务器的逻辑了,这里就不写了。

    1. 问题

    4.1 在于 3.3 这一步,微信返回的 code 不一定是有效的。。。之前逛其他地方,看到有人说微信的 webview 有个 bug ,会请求两次 callback url, 造成 code 重复使用,但是 TM 我把 callback 设置成一个静态页面,我手动拿这个 code 去微信查用户信息也失败了。

    4.2 业务服务器什么都不做修改,有时授权成功,有时授权失败(╯‵□′)╯︵┻━┻

    21 条回复    2016-09-05 17:00:14 +08:00
    abelyao
        1
    abelyao  
       2016-03-04 13:29:18 +08:00 via iPhone
    做过一个每天上万人访问的页面,也用到授权的,没遇过这样的问题。

    想不出为什么会造成两次访问 callback ,就算是两次,总有一次是没用过的 code 是正确的吧?正确了记录下来,重复的那个从数据库中先做个判断呢?
    chend
        2
    chend  
       2016-03-04 13:50:49 +08:00
    没遇到这种情况~~~
    只需要 appid 就能得到 code 了吧? 当然,你自己的 url 别带 code 这个参数,小心冲突~~
    用这个 code 取用户信息,貌似没遇到 code 无效的情况, access_token 倒是有失效的

    你先定位下问题, 会不会是重复请求了 两次,然后取了第一个 code ?
    huijiewei
        3
    huijiewei  
       2016-03-04 14:15:47 +08:00
    我能说的就是你的流程少步骤了,好好看文档,画画流程,不要脑补
    tinyproxy
        4
    tinyproxy  
    OP
       2016-03-04 14:29:09 +08:00
    @abelyao 请看 4.1 ,重定向到一个静态页面,我手动执行 **通过 code 换取网页授权 access_token **这一步也挂了。
    tinyproxy
        5
    tinyproxy  
    OP
       2016-03-04 14:29:18 +08:00
    @chend 请看 4.1 ,重定向到一个静态页面,我手动执行 **通过 code 换取网页授权 access_token **这一步也挂了。
    tinyproxy
        6
    tinyproxy  
    OP
       2016-03-04 14:32:22 +08:00
    @huijiewei 下面是微信文档的步骤, 2-4 是跟微信服务器打交道,一句话略过而已,这就叫脑补?
    ```
    1 第一步:用户同意授权,获取 code
    2 第二步:通过 code 换取网页授权 access_token
    3 第三步:刷新 access_token (如果需要)
    4 第四步:拉取用户信息(需 scope 为 snsapi_userinfo)
    5 附:检验授权凭证( access_token )是否有效
    ```
    Jacklee
        7
    Jacklee  
       2016-03-04 14:39:50 +08:00
    我猜有以下原因:
    1 、用户授权过之后,自己未缓存状态,每次进来都走一遍授权过程,用户一多流量一大授权接口就很频繁了。建议用户授权过后,拿到用户信息,缓存一段时间哪,这段时间不同授权。
    2 、 code 是一次性的,不能重复使用,第一次未成功,需要重新获取 code 的。

    3 、微信的问题,可能性不太大
    tinyproxy
        8
    tinyproxy  
    OP
       2016-03-04 14:55:31 +08:00
    @Jacklee
    1. 缓存是做了的, session 里面直接存了 15 天(连续 15 天不访问才会清理),如果用户的微信客户端会清理 cookie 那倒是有你说的可能,但是如果是这种情况必须重新授权了。

    2. code 是一次性的我在文档里面注意到了,所以我说我尝试重定向到一个静态页面去,然后手动把 code 粘贴出来手动做跟微信服务器的请求,然而这么做,抽风的时候也是直接挂掉。

    3. 我看过 log ,一个 code 就只用了一次,但是有时返回正确结果,有时就日狗了。

    4. 跟微信服务器的交互逻辑我想是理对了的,不然不会出现正常授权的情况才对(我们是偶尔正常,偶尔抽风),抽风的情况就是拿 code 找微信,然后没有正常返回
    chztv
        9
    chztv  
       2016-03-04 15:00:37 +08:00
    我们团队做了很多基于微信的 H5 页面,从来没有遇到这个问题过。
    BOYPT
        10
    BOYPT  
       2016-03-04 15:05:22 +08:00
    $auth = new WechatAuth(WXAPPID, WXAPPSEC);
    $tok = $auth->get_access_token($code);
    if($tok === False || !isset($tok['access_token']) || !isset($tok['openid'])) {
    error_log("Failed to get_access_token");
    }

    查了一下日志确实有类似情况,日志里面出现这句有好几次,不过也不算多,但是这种服务失效只能让用户重试啦~~
    Jacklee
        11
    Jacklee  
       2016-03-04 15:12:08 +08:00
    @tinyproxy 从你描述的情况看,时而抽风,时而成功。很大可能就是代码逻辑有问题,多理理,应该很快就发现问题了
    chend
        12
    chend  
       2016-03-04 15:12:13 +08:00
    @tinyproxy
    感觉似乎很蛋疼的样子, 只能一步一步试了~~
    先考虑 appid appsecret 不会出错~~

    1 : snsapi_userinfo 授权
    2 : code 来源 是不是每次 code 都是最新的, 逻辑那里会不会有 bug 用了 code 这个参数名,或者授权多次? 比如 微信授权后带有 code ,分享了这个链接
    3 :多跳转静态 用 code 调试吧~~~~
    tinyproxy
        13
    tinyproxy  
    OP
       2016-03-04 15:15:05 +08:00
    @BOYPT 终于找到一个跟我情况一样的了 T_T ,不过你比我好多了,我们是一段时间全部失效。。。然后又全部复活了。。。
    tinyproxy
        14
    tinyproxy  
    OP
       2016-03-04 15:16:13 +08:00
    @Jacklee 如果是代码逻辑问题,我手动拿 code 去处理不会出错吧,代码可以并发跑或者乱跑,我人总不行吧 T_T
    tinyproxy
        15
    tinyproxy  
    OP
       2016-03-04 15:18:55 +08:00
    @chend
    1. appid 跟 appsecret 第一个怀疑,但对了几遍都没错
    2. code 是微信给的,只有一个来源,就是用户在微信服务器那边同意授权后通过 callback url 给我们
    BOYPT
        16
    BOYPT  
       2016-03-04 15:27:45 +08:00
    说检查逻辑的估计没弄过 jssdk 了啦……都是封装好的方法,直接调用,没什么能控制的逻辑……
    我的方法是反正拿不到就重定向用户,重来,反正用户授权过之后也不会要求重新授权,影响不大。所以我没仔细看日志都没发现有这个情况……
    @tinyproxy
    Jacklee
        17
    Jacklee  
       2016-03-04 15:31:50 +08:00
    @tinyproxy 有个终极方案,可以尝试下,就是重置 appsecret (官方后台),排除账号问题。
    shiny
        18
    shiny  
       2016-03-04 15:31:51 +08:00
    有没有记录具体的错误代码
    qinxi
        19
    qinxi  
       2016-03-04 16:10:23 +08:00
    从未遇到过.....

    我的做法,先用 base 授权拿到 openid.查看 openid 是否在数据库(或者缓存也行)存在,存在就直接取出用户数据

    用户不存在 就跳转 userinfo 的链接让用户授权.拿到 code,换取 token.获取用户信息.存入数据库
    wand
        20
    wand  
       2016-03-04 20:26:08 +08:00
    搭车问一下,用微信授权登录第三方网站后,那里可以查看合取消这些授权?
    zhaohehe
        21
    zhaohehe  
       2016-09-05 17:00:14 +08:00
    你好,我今天也遇到这样的问题了,有时好,有时坏。不知道你找到解决的办法没
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1083 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 23:30 · PVG 07:30 · LAX 15:30 · JFK 18:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.