通过小程序实现微信扫码授权登录,网站接入微信扫码登录功能(永久免费)

需求

网站如果想要实现微信扫码登录其实有很多种方案,常见的方案就是微信开放平台和微信公众号服务号。前者是目前大部分网站并且是微信认可的一种方式,后者是开发者发现服务号具备扫码关注后即可获取用户基本信息的能力后而开发的一种方式。

而这两者其实都是需要具备资质,例如认证,对于个人开发者来说,是有一定的门槛的,而我这次分享的是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
// Header
header("Content-type:text/html;charset=utf-8");// 获取access_token
function getToken(){/*** 这里替换为你的小程序的appid和appsecret*/$appid='xxx';$appsecret='xxx';// 读取access_tokeninclude '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_tokenreturn $access_token['access_token'];}else{// 如果没有过期就直接读取缓存文件return $access_token['access_token'];}
}// 获取新的access_token
function 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的方式返回小程序码及scenereturn 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() {// 获取scenevar 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

<?php
header("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

<?php
header("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行的 a p p i d 和 appid和 appidappsecret要换成你的小程序的。以及92行的env_version在你的小程序上线后要改为release,如果是开发调试中,就保持现状。
2、login.php是小程序端向后端请求接口获取openid的,其中11行和12行的 a p p i d 和 appid和 appidappsecret要换成你的小程序的。
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://ma.liketube.cn/xcxqrcodelogin/creatqrcode.php

在这里插入图片描述

小程序端代码

以上仅为前端和后端的代码,小程序端的代码请点击这里下载。
小程序端代码:https://likeyun.lanzout.com/ii2Tp093wk6b

作者

TANKING
如需请教,可加WeChat: sansure2016

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/77655.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深入解析spring cloud gateway】08 Reactor 知识扫盲

一、响应式编程概述 1.1 背景知识 为了应对高并发服务器端开发场景&#xff0c;在2009 年&#xff0c;微软提出了一个更优雅地实现异步编程的方式——Reactive Programming&#xff0c;我们称之为响应式编程。随后&#xff0c;Netflix 和LightBend 公司提供了RxJava 和Akka S…

腾讯云centos7.6安装部署备忘

1.Mysql 1.1 安装mysql wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm rpm -ivh mysql-community-release-el7-5.noarch.rpm yum install mysql-community-server 1.1.1 安装后重启 service mysqld restart 1.1.2 初次安装mysql&#xff0c;root账…

【Python】【Fintech】用Python和蒙特卡洛法预测投资组合未来收益

【背景】 想利用蒙特卡洛方法和yahoo,stooq等财经网站上的数据快速预测特定portfolio的收益。 【分析】 整个程序的功能包括 读取json中的portfolio组合创建蒙特卡洛模拟预测收益的算法创建从财经网站获得特定投资组合数据,并根据2的算法获得该Index或Portfolio收益预测结…

ARTS打卡第四周之删除链表倒数第几个节点、gdb start命令、扩散模型、如何学习分享

Algorithm 题目&#xff1a;删除链表倒数第 n 个结点 分析&#xff1a;可以把通过两个结点进行标记&#xff0c;有一个节点需要遍历得快点&#xff0c;简称为快结点&#xff0c;有个结点遍历得慢&#xff0c;简称为慢结点。快结点先停在正数第 n 个结点处&#xff0c;然后快慢…

蓝桥杯打卡Day7

文章目录 阶乘的末尾0整除问题 一、阶乘的末尾0IO链接 本题思路&#xff1a;由于本题需要求阶乘的末尾0&#xff0c;由于我们知道2*510可以得到一个0&#xff0c;那么我们就可以找出2的数和5的数&#xff0c;但是由于是阶乘&#xff0c;所以5的数量肯定是小于2的数量&#xf…

车载Android应用开发与分析 - 初试 SystemUI Plugin

在前面的视频、文章中我们介绍完了整个车载Android应用开发所需要的基础知识&#xff1a; 【视频文稿】车载Android应用开发与分析 - 走进车载操作系统 - 掘金【视频文稿】车载Android应用开发与分析 - AOSP的下载与编译 - 掘金【视频文稿】车载Android应用开发与分析 - 开发系…

Elasticsearch:为具有许多 and/or 高频术语的 top-k 查询带来加速

作者&#xff1a;Adrien Grand Disjunctive queries&#xff08;term_1 OR term_2 OR ... OR term_n&#xff09;非常常用&#xff0c;因此在提高查询评估效率方面它们受到了广泛关注。 Apache Lucene 对于评估 disjunctive queries 有两个主要优化&#xff1a;一方面用于详尽评…

opencv(python)视频按帧切片/cv2.VideoCapture()用法

一、介绍 cv2.VideoCapture是OpenCV中一个用于捕捉视频的类。它可以访问计算机的摄像头&#xff0c;或从视频文件中读取图像。通过cv2.VideoCapture&#xff0c;用户可以轻松地捕捉、保存、编辑和传输视频流数据。 使用cv2.VideoCapture可以实现以下功能&#xff1a; 1. 打开…

计算机网络第四节 数据链路层

一&#xff0c;引入数据链路层的目的 1.目的意义 数据链路层是体系结构中的第二层&#xff1b; 从发送端来讲&#xff0c;物理层可以将数据链路层交付下来的数据&#xff0c;装换成光&#xff0c;电信号发送到传输介质上了 从接收端来讲&#xff0c;物理层能将传输介质的光&…

【Vue】一文让你进入Vue的大门

Vue简介 官网 ● 英文官网 ● 中文官网 介绍与描述 Vue历史 Vue 是一套用来动态构建用户界面的渐进式JS框架 构建用户界面&#xff1a;把数据通过某种办法变成用户界面 渐进式&#xff1a;Vue可以自底向上逐层的应用&#xff0c;简单应用只需要一个轻量小巧的核心库&#xff0c…

python 语法入门

文章目录 前言python 语法入门1. 语句分隔符2. 注释3. pep8规范4. 变量5. 扩展5.1. 运行此行代码的过程 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会…

【LeetCode刷题篇零】一些基础算法知识和前置技能(下)

数组常用技巧 使用数组代替Map 使用另一个数组来统计每个数字出现的次数&#xff0c;数组的下标作为key, 数组的值作为value&#xff0c; 将数字作为数组的下标索引&#xff0c;数组里的值存储该数字出现的次数&#xff0c;原理有点类似桶排序中使用的计数数组。 比如这里如…

小程序赖加载刷新数据页面数据堆叠问题debug

目录 项目所需 原生写赖加载存在的bug 解决问题思路及代码实现 思路&#xff1a; 代码实现&#xff1a; 列表.wxml 列表.js Wenjain_shanchu.js Wenjain_shanchu.json Wenjain_shanchu.wxml shouye.js ⭐️ 好书推荐 【内容简介】 项目所需 某高校大一新生入学&am…

EasyPHP-Devserver-17安装和配置mantisBT

文章目录 1、准备工作2、安装easyphp2.1 http://127.0.0.1 无法访问 3、安装mantisBT和phpMyAdmin3.1 配置浏览器的访问url和端口号&#xff08;配置局域网内可访问&#xff09;3.2 安装mantis 4、Administrator 注册新用户时设置登录密码5、附件上传6、邮件配置 文章参考自&am…

【广州华锐互动】煤矿提升机作业VR互动实训平台

在煤矿行业中&#xff0c;安全性是无可忽视的首要任务。传统的煤矿工人培训方法&#xff0c;如理论课堂讲解、实地操作演示&#xff0c;尽管具有一定的效果&#xff0c;但往往无法真实地模拟出煤矿的复杂环境&#xff0c;工作人员在没有真正接触煤矿的情况下&#xff0c;很难理…

【LLM】Windows本地CPU部署民间版中文羊驼模型(Chinese-LLaMA-Alpaca)踩坑记录

目录 前言 准备工作 Git Python3.9 Cmake 下载模型 合并模型 部署模型 前言 想必有小伙伴也想跟我一样体验下部署大语言模型, 但碍于经济实力, 不过民间上出现了大量的量化模型, 我们平民也能体验体验啦~, 该模型可以在笔记本电脑上部署, 确保你电脑至少有16G运行…

【GO语言基础】变量常量

系列文章目录 【Go语言学习】ide安装与配置 【GO语言基础】前言 【GO语言基础】变量常量 【GO语言基础】数据类型 文章目录 系列文章目录常量和枚举变量声明全局变量声明大小写敏感 总结 常量和枚举 使用const关键字声明常量&#xff0c;并为每个常量提供显式的值。Go语言没有…

嵌入式学习笔记(26)5S5PV210串行通信编程实战

5.5.1整个流程分析 整个串口通信相关程序包含2部分&#xff1a;uart_init负责初始化串口&#xff0c;uart_putc负责发送一个字节 5.5.2串口初始化关键步骤 &#xff08;1&#xff09;初始化串口的Tx和Rx引脚所对应的GPIO(查原理图可知Tx和Rx分别对应GPA0_1和GPA0_0) &#…

解决“您在 /var/spool/mail/root 中有新邮件”问题

一、发现问题 二、解决问题 1、删除邮件 cat /dev/null > /var/spool/mail/root 2、禁止系统启动邮件检查 echo "unset MAILCHECK" >> /etc/profile 三、解决结果

Matplotlib | 高阶绘图案例【3】- 五大战区高校排名

文章目录 &#x1f3f3;️‍&#x1f308; 1. 导入模块&#x1f3f3;️‍&#x1f308; 2. 数据处理2.1 高效数据2.2 学校排名 &#x1f3f3;️‍&#x1f308; 3. 绘图3.1 绘制图布&#xff0c;设置极坐标系3.2 绘制学校排名柱状图3.3 绘制五大战区扇形区域3.4 添加战区、学校…