二维码扫码登录详解【附简易实例代码(html+php+ios)】

来源:互联网 发布:mac dmg驱动装不上 编辑:程序博客网 时间:2024/05/21 10:05

1.前言

      我们在写一个不太了解的新功能的时候,又稳又快的一个方法就是借(chao)鉴(xi)其他的人的实现方法。所以我们先不急着开始写代码,先看一下各互联网巨头都是如何实现的。

首先来看一下淘宝的扫码登录:

这里写图片描述

F12调出控制台,可以看出淘宝一直在发送请求查看这个二维码的状态

这里写图片描述

可以看出京东也是这么做的,看到这里大家都有点思路了把

2.准备

接着我们还是不着急写代码,先把思路理清楚。这里我们采用前后端分离的方法来实现这个功能(暂不考虑二维码过期、该二维码登录过一次等复杂情况,只实现扫码登录功能)。

      2.1 首先梳理一下要准备的PHP接口,一共有3个:

          1.让前端页获取唯一的QRUUID(唯一字符串就可以)生成一个二维码用的接口。
         2.APP端扫描到QRUUID后去请求的接口,功能是把用户和这个QRUUID绑定(可以传User_id或者token什么的,具体看需求)。
         3.前端在获取到第一个的接口返回的QRUUID后去轮询请求的接口,功能是查询这个QRUUID是不是被APP端扫描并绑定。

      2.2 然后是HTML页的主要实现:

          其实就是Ajax请求PHP接口获得QRUUID然后生成二维码,接着使用setInterval() 方法去请求第三个PHP接口。(前端生成二维码的开放API:http://www.topscan.com/pingtai/)

      2.3 最后是APP端(以iOS为例)的实现:

          使用AVFoundation扫描二维码获得信息,然后请求PHP接口将用户数据和QRUUID绑定。

3.代码

      3.0 简易数据库表:

DROP TABLE IF EXISTS `qrcodelogin`;CREATE TABLE `qrcodelogin` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `qruuid` varchar(15) NOT NULL DEFAULT '',  `user_id` int(11) DEFAULT NULL,  `user_token` varchar(255) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB;SET FOREIGN_KEY_CHECKS = 1; 

      3.1 先放上PHP的3个接口的代码:

<?php//config.php 数据库配置文件$db_host = '192.168.1.103';$db_name = 'test';$db_user = 'root';$db_pwd = 'a123456';
<?php/** * getqruuid.php * 用于前端获取qruuid(二维码唯一ID)使用 * * User: caohan */require('config.php');$mysqli = new mysqli($db_host, $db_user, $db_pwd, $db_name);if (mysqli_connect_error())    echo mysqli_connect_error();$mysqli->set_charset("utf8");//生成随机的UUID 用于二维码显示的内容 和 绑定用$qruuid = substr(md5(uniqid(mt_rand(), true)), 0, 15);//生成uuid$sql = "insert into qrcodelogin (qruuid) values ('". $qruuid ."')";$result = $mysqli->query($sql);if($result === false){    echo $mysqli->error;    echo $mysqli->errno;}$mysqli->close();$arr = ['code'=>1, 'msg' => '生成qruuid成功','data'=>$qruuid];echo json_encode($arr);exit();
<?php/** * bindqruuid.php * App端扫描二维码获得qruuid以后 * 然后请求这个接口  二维码的qruuid和用户绑定并把用户信息传入 * (token或者user_info什么的 具体看需求) * * User: caohan */require('config.php');$mysqli = new mysqli($db_host, $db_user, $db_pwd, $db_name);if (mysqli_connect_error())    echo mysqli_connect_error();$mysqli->set_charset("utf8");$qruuid = $_GET['qruuid'];$user_id = $_GET['user_id'];$user_token = $_GET['user_token'];$sql = "update qrcodelogin set user_id='" . $user_id . "',user_token='" . $user_token . "' where qruuid='" . $qruuid . "'";$result = $mysqli->query($sql);if ($result === false) {    echo $mysqli->error;    echo $mysqli->errno;}$mysqli->close();$arr = ['code' => 1, 'msg' => '绑定成功'];echo json_encode($arr);exit();
<?php/** * checkqruuid.php * 用于前端页轮询 查询该qruuid是否被绑定 *  * User: caohan */require('config.php');$mysqli = new mysqli($db_host, $db_user, $db_pwd, $db_name);if (mysqli_connect_error())    echo mysqli_connect_error();$mysqli->set_charset("utf8");$qruuid = $_GET['qruuid'];$sql = "select * from qrcodelogin where qruuid='" . $qruuid . "'";$result = $mysqli->query($sql)->fetch_array();if ($result === false) {    echo $mysqli->error;    echo $mysqli->errno;}$mysqli->close();if (!is_null($result['user_id']))    $arr = ['code' => 1, 'msg' => '登录成功', 'data' => $result];else    $arr = ['code' => 500, 'msg' => 'qruuid暂时未被绑定','data'=>$qruuid];echo json_encode($arr);exit();?>

      3.2 HTML页的代码:

<html>    <head>        <script  src="http://libs.baidu.com/jquery/1.7.2/jquery.min.js"></script><!--在线jq引用-->        <title>这个一个二维码登录页Demo</title>    </head>    <body>        <h4>            这个一个二维码登录页Demo        </h4>        <h5>            用APP扫描下方二维码模拟登录        </h5>        <img id="qrcodeimg" />    </body>    <script>        $.ajax({            type: "GET",            url: "getqruuid.php",            data: {},            success: function (result) {                var data = JSON.parse(result);                if (data.code == 1) {                    //显示到网页上  免费在线二维码生成的API                    $("#qrcodeimg").attr('src', 'http://qr.topscan.com/api.php?text=' + data.data);                    //轮询 查询该qruuid的状态 直到登录成功或者过期(过期这里没判断,留给大家)                    var interval1= setInterval(function () {                        $.ajax({                            type: "GET",                            url: "checkqruuid.php",                            data: {'qruuid': data.data},                            success: function (result) {                                var data = JSON.parse(result);                                if (data.code == 1) {                                    alert('扫码成功(即登录成功),进行跳转.....');                                    //停止轮询                                    clearInterval(interval1);                                    //TODO 拿到需要的信息 然后跳转什么的                                }                            }                        });                    }, 1000);//1秒钟  频率按需求                }            }        });    </script></html>

      3.3 APP的核心代码:

////  ViewController.m//  QRCode#import "ViewController.h"#import "QRCodeViewController.h"@interface ViewController () <QRCodeViewControllerDelegate>@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];}- (IBAction)scanCode:(UIButton *)sender {    QRCodeViewController *qrVc = [[QRCodeViewController alloc] init];    qrVc.delegate = self;    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:qrVc];    // 设置扫描完成后的回调    __weak typeof (self) wSelf = self;    [qrVc setCompletionWithBlock:^(NSString *resultAsString) {        [wSelf.navigationController popViewControllerAnimated:YES];//        [[[UIAlertView alloc] initWithTitle:@"扫描完成" message:resultAsString delegate:self cancelButtonTitle:@"好的" otherButtonTitles: nil] show];    }];    [self presentViewController:nav animated:YES completion:nil];}#pragma mark - 代理方法- (void)reader:(QRCodeViewController *)reader didScanResult:(NSString *)result{    NSLog(@"%@",result);    //模拟用户已登录状态    //创建假的user_id和假的user_token用于绑定(根据实际需求传递参数)    NSInteger user_id = 1;    NSString *user_token = @"this_is_user_token";    [self dismissViewControllerAnimated:YES completion:^{        //请求服务端接口        NSError *error;        NSString *urlString = [NSString stringWithFormat:@"http://192.168.1.103/qrcodelogin/bindqruuid.php?qruuid=%@&user_id=%ld&user_token=%@",result,(long)user_id,user_token];        //加载一个NSURL对象        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];        //将请求的url数据放到NSData对象中        NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];        NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];        NSLog(@"接收到的数据为%@",jsonDic);    }];}@end

PS:我在CSDN下了一个扫描二维码的Demo,并且修改一下,这里放出我下载的Demo的地址:http://download.csdn.net/download/u013438373/9808825

4.实现效果

HTML登录页

这里写图片描述

APP扫码过程

这里写图片描述

扫描后的网页

这里写图片描述

5.项目GitHub地址

      https://github.com/CaoHan/qrcodelogin

原创粉丝点击