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

2018-02-22 19:58:20 +08:00
 edison111cry

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

通过: 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

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

11857 次点击
所在节点    问与答
11 条回复
qiayue
2018-02-22 20:01:15 +08:00
专门有一个回调页面
http://www.test.com/callback.php?code=CODE&state=STATE
在这个页面处理完后登录或注册逻辑后跳回到你的业务页面
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
2018-02-22 20:17:13 +08:00
可以利用一下 cookie。比如在回调成功后,cookie 中存一个 token。处理此页面时,先检查 cookie 中的 token 是否合法,若合法则跳过微信授权。
edison111cry
2018-02-22 20:26:45 +08:00
@qiayue 谢谢,如果按你说的分开的话,如果在需要显示的页面里展示微信头像或者昵称的话都是通过在业务页面里放到 cookie 里吗? 所以用户如果刷新这个业务页面的话,永远都是在 cookie 里取?
qiayue
2018-02-22 20:34:50 +08:00
首先,所有数据都需要保存到数据库中,除非你单用户应用,不然我想看别人的头像怎么办
然后,看你的实现逻辑了,当前登录用户信息,可以放在 session 中,也可以放 cookie 中,但是最好 cookie 中只是保存一个 sessionid 就好了,cookie 中不要保存敏感信息。
woscaizi
2018-02-22 21:09:49 +08:00
登录信息放 session,当前页面的 url 先判断 session 中的登录信息,没有再根据 code 获取,获取后就放 session 中。
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
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
2018-02-24 12:43:36 +08:00
@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
2018-02-24 12:46:10 +08:00
@odirus 但要注意错误处理

例如 3 当用户在微信中没有进行授权,貌似也会回调,不过不会带上 code
例如 SCOPE 要合理选取,静默授权的话只能获取 openid,但要配合 APP 或者其他微信公众号,最好还是要获取 unionId,不然以后几个应用不能互相关联起来。
edison111cry
2018-02-24 13:29:10 +08:00
@odirus 大兄弟,非常感谢哈,现在很清楚了。以前我都是在 REDIRECT_URI 里面直接获取到用户的头像信息等并直接展示,然后如果用户在右上角点击刷新当前页面时就会取不到。我当时只能在这个 REDIRECT_URI 里面再判断是否取到了 openid,如果没有再跳转回 http://test.com/home 这个页面让它通过这个里面的代码重定向到微信的验证链接,然后再次跳到 REDIRECT_URI,虽然也可以实现。不过总觉得不是太妥当。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/431734

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX