公众号扫码登录逻辑
公众号扫码登录
用户在网页点“微信登录”,网页先去你服务端要一个“登录二维码”。你服务端为了能调用微信接口,先拿(或从缓存取)公众号的 access_token,然后调用微信的“创建带参数二维码”接口 /cgi-bin/qrcode/create,把一个你生成的参数(通常叫 scene,你可以理解为一次性的 ticket/登录编号)塞进请求里。微信返回一个 ticket(以及过期时间),网页拿到这个 ticket 后,不是让你服务端自己画二维码,而是直接用微信的展示地址 https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=xxx 当作图片链接显示在 <img> 上,浏览器就能看到二维码了(注意这个接口返回的是图片二进制,不是 JSON)。
接着用户用微信扫码。扫码后微信会把这个二维码里携带的参数(EventKey,就是你当初的 scene/ticket)连同用户身份(FromUserName,也就是 openid)以 XML 回调到你配置的公众号服务器地址。你服务端收到回调后,做一件最关键的事:把 ticket ↔ openid 绑定保存起来(你现在用 Guava 缓存 openidToken.put(ticket, openid) 就是这个动作)。这一步完成后,说明“这个二维码对应的网页已经被谁扫了”已经在你服务端有结果了。你还可以顺便给这个 openid 发一条模板消息提示“登录成功”(可选,但体验好)。
与此同时网页端会一直轮询你的服务端,比如每隔 1 秒调用一次 checkLogin(ticket)。只要用户还没扫码,你服务端就返回空;一旦扫码回调把 ticket-openid 绑定写入缓存,轮询就能拿到 openid(或你生成的登录态 token)。网页拿到成功结果后,就把登录态写进 cookie/session/localStorage(取决于你怎么做),然后跳转到已登录页面——整个扫码登录就完成了。
二维码里放 ticket(一次性凭证),扫码回调拿到 openid(用户身份),服务端把两者绑定,网页轮询拿结果完成登录。
