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

微信授权跳转后怎么处理用户在当前页面主动刷新

  •  
  •   edison111cry · 2018-02-22 19:58:20 +08:00 · 11841 次点击
    这是一个创建于 2261 天前的主题,其中的信息可能已经有所发展或是发生改变。

    按照微信开发文档上说明:

    通过: https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

    假设 REDIRECT_URI 是 http://www.test.com/index.php

    然后微信把页面链接回变成: http://www.test.com/index.php?code=CODE&state=STATE

    接下来获取用户的 open_id 和身份信息。

    但是问题来了,如果用户在当前页面点击刷新(当前页面的 URL 是: http://www.test.com/index.php?code=CODE&state=STATE

    这个 CODE 已经失效,获取不到 open_id 了,所以这种情况下该咋办,当前处理的方法是如果获取不到 open_id,再跳转回 https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

    虽然可行,但是总感觉不太好,大神们都是怎么处理的

    11 条回复    2018-02-24 13:29:10 +08:00
    qiayue
        1
    qiayue  
       2018-02-22 20:01:15 +08:00   ❤️ 1
    专门有一个回调页面
    http://www.test.com/callback.php?code=CODE&state=STATE
    在这个页面处理完后登录或注册逻辑后跳回到你的业务页面
    qiayue
        2
    qiayue  
       2018-02-22 20:06:58 +08:00
    一个 URL 只做一件事情
    一件事情确保只有一个 URL

    举个例子,用户登录之后显示个人信息页面,那么你需要三个 URL
    url 1: /login.htm 登录表单页面,用于输入账号密码信息
    url 2: /do_login 登录逻辑处理,接收表单提交过来的账号密码信息
    url 3: /user.html 用户个人信息页面,登录逻辑处理完成后跳转到这里

    而不应该在 /do_login 里边处理完登录后直接显示用户信息
    hotea
        3
    hotea  
       2018-02-22 20:17:13 +08:00
    可以利用一下 cookie。比如在回调成功后,cookie 中存一个 token。处理此页面时,先检查 cookie 中的 token 是否合法,若合法则跳过微信授权。
    edison111cry
        4
    edison111cry  
    OP
       2018-02-22 20:26:45 +08:00
    @qiayue 谢谢,如果按你说的分开的话,如果在需要显示的页面里展示微信头像或者昵称的话都是通过在业务页面里放到 cookie 里吗? 所以用户如果刷新这个业务页面的话,永远都是在 cookie 里取?
    qiayue
        5
    qiayue  
       2018-02-22 20:34:50 +08:00   ❤️ 1
    首先,所有数据都需要保存到数据库中,除非你单用户应用,不然我想看别人的头像怎么办
    然后,看你的实现逻辑了,当前登录用户信息,可以放在 session 中,也可以放 cookie 中,但是最好 cookie 中只是保存一个 sessionid 就好了,cookie 中不要保存敏感信息。
    woscaizi
        6
    woscaizi  
       2018-02-22 21:09:49 +08:00 via iPhone
    登录信息放 session,当前页面的 url 先判断 session 中的登录信息,没有再根据 code 获取,获取后就放 session 中。
    odirus
        7
    odirus  
       2018-02-22 23:36:40 +08:00
    我们的方案是:

    REDIRECT_URI (假设为 wechat_redirect_uri )负责的职责:
    根据 code 获取 openid 或者 unionId => 根据 openid 或者 unionId 查询用户 ID => 执行登录流程,并通过 cookie 写入 session 信息

    REDIRECT_URI 中可以加入用户请求的目标业务的 REDIRECT_URI (假设为 user_redirect_uri )

    当用户授权之后,微信会回调到 wechat_redirect_uri 上,服务端处理完各种流程后,再回调到 user_redirect_uri 上


    这种方案需要考虑在各个环节出错后的异常处理(例如 access_token 出错导致根据 code 获取 openid 不成功),避免一直在进行反复地回调跳转,用户会晕菜的。
    edison111cry
        8
    edison111cry  
    OP
       2018-02-24 09:01:40 +08:00
    @odirus 谢谢这么详细的描述。有一点想要再请教下:

    在 user_redirect_uri 里,首先判断是否存在 session 信息,如果没有的话就通过服务器端跳转:
    (第一次跳转到:) https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

    (第二次跳转到:) wechat_redirect_uri :在这个里面获取到 openid 等信息,然后放入 session,然后再次跳转到
    user_redirect_uri
    odirus
        9
    odirus  
       2018-02-24 12:43:36 +08:00   ❤️ 1
    @edison111cry

    第一步:
    当用户请求某个页面(例如用户主页 http://test.com/home )的时候(服务端正在处理,还未返回页面或接口信息的时候),服务端通过判断 cookie 中的 sessionid 发现用户未登陆或者登陆已失效,这时就不返回页面内容,而是让用户重定向到下面这个地址:

    https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

    其中 REDIRECT_URI 应该是 "http://test.com/openauth/wechat?redirect_uri=http://test.com/a" (注意转义哈,我这里只是用于讲解)

    备注:假设你的业务系统中,专门处理微信授权登录功能的 URL 是: http://test.com/openauth/wechat

    第二步:
    拼装完 REDIRECT_URI 后,就是用户首先会跳转到的微信授权页面地址,大致流程是:
    1. 当发现用户未登录的时候
    2. 重定向到微信授权页面,授权成功后会跳转到 REDIRECT_URI
    3. 根据 code 获取必要的信息(例如 openid 甚至是 unionId )
    4. 获取到了用户 ID,并执行了登录流程后,通过 cookie 写入 session 信息
    5. 跳转到用户最开始真正需要请求的页面上
    odirus
        10
    odirus  
       2018-02-24 12:46:10 +08:00
    @odirus 但要注意错误处理

    例如 3 当用户在微信中没有进行授权,貌似也会回调,不过不会带上 code
    例如 SCOPE 要合理选取,静默授权的话只能获取 openid,但要配合 APP 或者其他微信公众号,最好还是要获取 unionId,不然以后几个应用不能互相关联起来。
    edison111cry
        11
    edison111cry  
    OP
       2018-02-24 13:29:10 +08:00
    @odirus 大兄弟,非常感谢哈,现在很清楚了。以前我都是在 REDIRECT_URI 里面直接获取到用户的头像信息等并直接展示,然后如果用户在右上角点击刷新当前页面时就会取不到。我当时只能在这个 REDIRECT_URI 里面再判断是否取到了 openid,如果没有再跳转回 http://test.com/home 这个页面让它通过这个里面的代码重定向到微信的验证链接,然后再次跳到 REDIRECT_URI,虽然也可以实现。不过总觉得不是太妥当。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   750 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 21:00 · PVG 05:00 · LAX 14:00 · JFK 17:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.