需要
网站如果想要实现微信扫码登录其实有很多种计划,常见的计划就是微信开放平台和微信公众号服务号。前者是目前大部分网站并且是微信认可的一种形式,后者是开发者发现服务号具备扫码关注后即可获取用户根本信息的能力后而开发的一种形式。
而这两者其实都是须要具备资质,例如认证,对于集体开发者来说,是有肯定的门槛的,而我这次分享的是0门槛的,集体开发者一样能够实现。
原理
小程序也是具备获取用户根本信息的能力的,能够调用wx.login接口
获取用户的openid实现登录。简略来说就是web端创立一个带参数的二维码同时向数据库插入一条登录记录,此时web端曾经开始轮询数据库这条记录的扫码状态了,微信扫码后关上小程序并立刻获取到这个参数,而后点击受权登录按钮申请wx.login这个接口获取到openid,而后将openid更新至数据库这个登录记录中并更新扫码状态,web端能够轮询到登录胜利的状态码就展现登录胜利。
代码
creatqrcode.php
<!DOCTYPE html><html><head> <title>小程序扫码登录示例</title> <meta charset="utf-8"> <script type="text/javascript" src="./jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="./bootstrap.min.css"> <style> *{ padding:0; margin:0; } #xcxqrcode{ width: 200px; height: 200px; margin:50px auto; display: block; } #lgtext{ text-align: center; padding:20px 20px; background: #f1f1f1; border-radius: 100px; } #openid{ text-align: center; padding:20px 20px; } </style></head><body><?php// Headerheader("Content-type:text/html;charset=utf-8");// 获取access_tokenfunction getToken(){ /** * 这里替换为你的小程序的appid和appsecret */ $appid='xxx'; $appsecret='xxx'; // 读取access_token include 'access_token.php'; // 判断是否过期 if (time() > $access_token['expires']){ // 如果曾经过期就得从新获取并缓存 $access_token = array(); $access_token['access_token'] = getNewToken($appid,$appsecret); $access_token['expires']=time()+7000; // 将数组写入php文件 $arr = '<?php'.PHP_EOL.'$access_token = '.var_export($access_token,true).';'.PHP_EOL.'?>'; $arrfile = fopen("./access_token.php","w"); fwrite($arrfile,$arr); fclose($arrfile); // 返回以后的access_token return $access_token['access_token']; }else{ // 如果没有过期就间接读取缓存文件 return $access_token['access_token']; }}// 获取新的access_tokenfunction getNewToken($appid,$appsecret){ $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}"; $access_token_Arr = https_request($url); return $access_token_Arr['access_token'];}// curl申请函数function https_request ($url){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $out = curl_exec($ch); curl_close($ch); return json_decode($out,true);}// 创立小程序码function creatQrcode(){ // 申请小程序接口创立小程序码 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token='.getToken()); curl_setopt($ch, CURLOPT_POST, true); $sc = uniqid(); // 生成scene $data = array( "scene" => $sc, "env_version" => "develop" // 小程序审核通过后须要批改参数为release ); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); // 图片buffer转本地图片 $img = file_put_contents($sc.'.png', $result); // 引入数据库配置 include './Db.php'; // 将二维码的scene写入数据库 $add_scene = "INSERT INTO xcxqrcodelogin (scene) VALUES ('$sc')"; if ($conn->query($add_scene) === TRUE) { $file = $sc.'.png'; if($fp = fopen($file,"rb", 0)) { $gambar = fread($fp,filesize($file)); fclose($fp); $base64_qrcode = 'data:image/jpg/png/gif;base64,'.chunk_split(base64_encode($gambar)); // 以JSON的形式返回小程序码及scene return json_encode(array('xcxqrcode'=>$base64_qrcode,'scene'=>$sc)); } } // 断开连接 curl_close($ch); $conn->close();}?><!-- 获取到小程序码的base64数据 --><?php $qrcodebase64json = json_decode(creatQrcode()); $xcxqrcode = $qrcodebase64json->xcxqrcode; $scene = $qrcodebase64json->scene; // 删除本地的图片 unlink('./'.$scene.'.png');?><!-- 展现二维码及扫码后果 --><div style="width:300px;margin:50px auto;"> <img src="<?php echo $xcxqrcode; ?>" id="xcxqrcode"> <input type="hidden" value="<?php echo $scene; ?>" id="sc"/> <h4 id="lgtext">请应用微信扫码</h4> <p id="openid"></p></div><!-- 轮询扫码后果 --><script type="text/javascript">// 从0秒开始轮询let TimeOut = 0;let checklogin = setInterval('CheckStatus()', 1000);// 查问扫码状态function CheckStatus() { // 获取scene var sc = $('#sc').val(); $.ajax({ type: "POST", url: "./getstatus.php?scene="+sc, success:function(data){ // code==200即受权登录胜利 if (data.code == 200) { console.log(data.msg) $('#lgtext').html('<span style="color:#07c160;">'+data.msg+'</span>') $('#openid').text(data.openid) $('#xcxqrcode').css('filter','blur(5px)') clearTimeout(checklogin); }else{ console.log(data.msg) if(data.code == 201){ $('#lgtext').html('<span style="color:#666;">'+data.msg+'</span>') }else if(data.code == 202){ $('#lgtext').html('<span style="color:#07c160;">'+data.msg+'</span>') } } guoqi(); }, error:function(data) { console.log('服务器产生谬误') $('#lgtext').text('服务器产生谬误') } });}// 小程序码过期检测function guoqi(){ TimeOut += 1; // 60秒后过期 if(TimeOut >= 60){ // 过期后进行轮询 clearTimeout(checklogin); $('#lgtext').text('已过期,请刷新页面') $('#xcxqrcode').css('filter','blur(5px)') }}</script></body></html>
getstatus.php
<?phpheader("Content-type:application/json");// 小程序扫码后解析小程序码获取到的scene$scene = $_GET['scene'];// 引入数据库配置include './Db.php';// 查问以后scene的扫码状态$getstatusinfo = "SELECT * FROM xcxqrcodelogin WHERE scene='$scene'";$result_statusinfo = $conn->query($getstatusinfo);// 如果scene存在if ($result_statusinfo->num_rows > 0) { while($row_statusinfo = $result_statusinfo->fetch_assoc()) { $status = $row_statusinfo['status']; $openid = $row_statusinfo['openid']; } // 当scene=1的时候代表还没扫码 if($status == '1'){ $ret = array( 'code' => 201, 'msg' => '请应用微信扫码' ); }else if($status == '2'){ // 当scene=2的时候代表已扫码未登录 $ret = array( 'code' => 202, 'msg' => '已扫码,请受权登录' ); }else if($status == '3'){ // 当scene=3的时候代表已登录 $ret = array( 'code' => 200, 'msg' => '登录胜利', 'openid' => $openid ); }}else{ $ret = array( 'code' => 203, 'msg' => '请刷新重试' );}// 断开数据库连贯$conn->close();// 输入后果echo json_encode($ret,JSON_UNESCAPED_UNICODE);?>
scanCode.php
<?php/** * 通知数据库我曾经扫码了 */header("Content-type:application/json");$scene = $_GET['scene'];// 引入数据库配置include './Db.php';mysqli_query($conn,"UPDATE xcxqrcodelogin SET status='2' WHERE scene='$scene'");$conn->close();?>
login.php
<?phpheader("content-type:application/json");// 通过wx.login获取到的code$code = $_GET["code"];$scene = $_GET['scene'];/** * 这里替换为你的小程序的appid和appsecret */$appid = "xxx";$secret = "xxx";// 申请接口进行登录获取到openid$api = "https://api.weixin.qq.com/sns/jscode2session?appid=$appid&secret=$secret&js_code=$code&grant_type=authorization_code";$result = file_get_contents($api);$arr_result = json_decode($result, true);$openid = $arr_result["openid"];// 引入数据库配置include './Db.php';// 更新登录状态mysqli_query($conn,"UPDATE xcxqrcodelogin SET openid='$openid',status='3' WHERE scene='$scene'");$ret = array( 'code' => 200, 'msg' => '登录胜利', 'openid' => $openid);$conn->close();// 返回后果echo json_encode($ret,JSON_UNESCAPED_UNICODE);?>
Db.php
<?php/** * 数据库配置 * BY TANKING 2022-08-06 * https://segmentfault.com/u/tanking */$db_url = "XXX"; // 数据库服务器地址$db_user = "XXX"; // 数据库账号$db_pwd = "XXX"; // 数据库账号$db_name = "XXX"; // 数据库名称// 连贯数据库$conn = new mysqli($db_url, $db_user, $db_pwd, $db_name);mysqli_query($conn, "SET NAMES UTF-8");?>
代码阐明
1、creatqrcode.php
是生成小程序码的界面,其中41行和42行的$appid和$appsecret要换成你的小程序的。以及92行的env_version在你的小程序上线后要改为release
,如果是开发调试中,就放弃现状。
2、login.php
是小程序端向后端申请接口获取openid的,其中11行和12行的$appid和$appsecret要换成你的小程序的。
3、scanCode.php
是扫码后通知服务器你曾经实现扫码的后端。
4、getstatus.php
是轮询扫码状态的后端。
5、Db.php
是数据库配置文件,须要进去配置你的数据库地址、账号、明码、数据库名称。
数据库创立
将这条SQL粘贴至你的数据库治理端进行创立数据库表。
CREATE TABLE `xcxqrcodelogin` ( `id` int(11) NOT NULL AUTO_INCREMENT, `scene` varchar(32) DEFAULT '', `openid` varchar(32) DEFAULT '', `status` varchar(2) DEFAULT '1' COMMENT '1未扫码2已扫码3已登录', `creat_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=148 DEFAULT CHARSET=utf8mb4
Demo
小程序端代码
以上仅为前端和后端的代码,小程序端的代码请点击这里下载。
小程序端代码:https://likeyun.lanzout.com/i...
作者
TANKING
如需求教,可加WeChat:sansure2016