关于PHP实现扫码登录
1.实现APP手机登陆后扫码登录PC端
登录的原理
登录的原理无非就是session或者cookie的同步,或者基于API模式(利用nosql来记录标识),将用户信息共享多端。然而,这里用的是session,session是连接客户端和服务器的重要部分。但是,不同的客户端连接服务器会产生不同的session,那么实现APP登录后同步到浏览器的关键就是,同步这两个客户端的session。
关键:如何使两个客户端的session同步
其实服务器在和客户端进行通信的时候产生的每一个session都是带有一个唯一的id的,至于这个id我们可以用session_id()得到。既然我们可以得到session_id了,接下来就是实现session同步了。关键点还是这个函数,session_id(),这个函数不仅可以得到本次session的id,还能让当前的session成为一个已知的session_id的session,即修改本次的session_id。
例如,在PC端获取到了APP端的session_id,假设为1,将扫码后的访问路径生成一个二维码,其中,将这个APP端的session_id作为参数,放入回调地址中。让APP在扫码授权后,回调到我制定的控制器,去同步session的内容。
这里模仿授权后获取到了用户的信息:
// 首先我判断这次回调是否带上了sessionid参数
if($sessionid = $_GET[‘sessionid’]){
// 将sessionid存入session,避免get的过程中丢失
$_SESSION[‘session_id’] = $sessionid;
}
// 在获取用户微信信息后加入以下代码
if($sessionid = $_SESSION[“session_id”]){
unset($_SESSION[“session_id”]);
$session = $_SESSION;
// 同步PC和微信端的session
session_id($sessionid);
// 将获取到的微信信息存入这个共同session中
$_SESSION = $session;
// 启用这个session,关键,一定要使用这步
session_start();
}
到此,PC端和APP端的session就同步了,可以在用户打开扫码的同时开启一个ajax,定时访问某个接口,判断session值是否改变,如果改变就跳转到指定页面,这样就实现了微信扫码登录。
2.进一步实例了解-----重点
如淘宝,腾讯等网站登录页面,都有APP扫码登录这个功能。现基于此,做一个自己的APP扫码登录功能。
思路:①生成一个二维码, 二维码链接带有密钥. (参数主要有回调地址,以及随机字符串,生成时间等参数,做有效期校验).② 用数据库表记录这次的密钥, 方便APP返回用户ID时比对. ③前端页面需要进行ajax轮询,去获取用户是否登陆的状态,并拿到相应的登录信息,例如token.
image一. 点击右上角时, 要ajax生成一个二维码. 不要一开始就生成, 或许别人不用扫码登录
image二. 二维码生成方法.
前端, 切换二维码登录时触发, 所以要用ajax,去填充iframe, 当然你可以直接给iframe的src上加二维码的方法路径。(获取二维码的方法在服务端)
三.生成二维码后, sign的密钥就写入了数据库, 前端ajax开始轮询,如果轮询为1,则说明已经登录
image四. 我是统一写的一个apilogin控制器, 这个是二维码生成方法. 方法里带有sign,主要就是这个. sign方法是oauth2.0协议。
二维码生成的只是个链接, url的话, 是一个回调的接口地址, 为了安全,其实可以略去, 只用网址加参数。注意:应该将token(这里值sign值)参数也加到链接参数里,这里省去了
五. 这时 APP端需要实现“扫码功能”, 扫码后,手机app端就读取到了这个网址链接, 获得了参数, APP端点击确认登录按钮。
image六.APP端确认时,根据获取的链接url进行验证sign密钥, 如果正确就跳转到接收到的url接口地址, 并且带上sign签名(token), addtime当前时间,userid等信息。
token和url是扫码获得的, 再返回给接口. addtime是确认时间, 可以做过期验证. userid是手机端用户id, 可以进行加密保护, 也可以直接明文, 反正别人看不到。
七. 回调方法, 接收APP返回的接口,根据token去查询二维码登录表.(这里username指的是userid)
image八.数据库字段(验证二维码链接的表字段信息)
(id, uname 用户id, token 签名, add_time生成时间, return_time 回调时间)
当PC端生成时, 是没有用户ID的, APP扫码后,回调给了用户ID, 需要更新扫码的用户信息。
九. 最后PC端的轮询. 轮询前端探查是否扫码登录状态并获取相关登录信息, 我加了个计数变量, 避免长时间轮询消耗资源。
image这里除了返回1之外,还需要返回一些用户信息等给客户端保存记录
上面点击二维码时, 生成二维码 , 有个开始轮询, 3秒执行一次轮询, 轮询方法里面还加了一个计算, 执行一次+1, 达到20次时, 20*3=60秒.刷新一次页面.
9.ajax轮询的请求方法, 根据当前session记录的sign进行查询, 这是为了避免客户端开多个窗口同时扫码,
image10.查询到以后, 写入session和cookie,方便客户端读取, 以及返回1 ,告诉前端, 登录成功进行跳转到index首页。
注意以上只是提供一个思路,如果你是写API的方式,可以通过缓存例如redis等方法记录相应的数据,根据请求确定的唯一标识来查找扫码的数据(可以在生成二维码的时候生成唯一标识存入缓存中,并返给前端,之后传过来查询该标识是否有用户信息存在,对于标识可以采取加密解密的方式更加安全,服务端的加密解密过程)