前言
记录一下自己实现微信登陆的艰难历程,希望能对大家有所帮助。
一、微信公众号申请
1.点击下方地址进入
https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
2.接口配置信息的修改
eg:之前在这里卡了很久一直不知道怎么弄,最后经过不断的尝试发现想要修改成功首先你得有一个域名和服务器,它的大概实现图如下
具体实现
- (1)申请域名并成功部署服务器(此处不懂,点击此处)
注:因为本人使用的宝塔面板,此处就以宝塔面板为例 - (2)在宝塔面板的软件管理下载php环境,并在部署域名的时候选择php环境
- (3)在域名的根目录下新建一个php文件,并在该文件下输入以下代码
if ('notify' == $type) {
echo $_GET['echostr'];
}
注:若此处申请失败可以使用官网的代码
- (4)接口URL填写格式详述
- (5)成功后系统反馈回修改成功,此时就大功告成了,接下来就是二维码得提取了和回调了
二、利用php代码实现二维码的获取
eg:这里就直接给源码了(内涵具体注释),源码所放位置为刚刚在域名根目录下所建立的php文件内
1.引入库
代码如下(示例):
<?php
header('Content-Type: text/html;charset=utf-8');
header('Access-Control-Allow-Origin:http://localhost:8080'); // *代表允许任何网址请求
header('Access-Control-Allow-Methods:POST,GET,OPTIONS,DELETE'); // 允许请求的类型
header('Access-Control-Allow-Credentials: true'); // 设置是否允许发送 cookies
header('Access-Control-Allow-Headers: Content-Type,Content-Length,Accept-Encoding,X-Requested-with, Origin'); // 设置允许自定义请求头的字段
require './vendor/autoload.php';
$type = $_GET['type'];
$config['app_id'] = 'xxx';//你的微信公众平台的app_id
$config['secret'] = 'xxx';//你的微信公众平台的secret
$config['expire'] = 60;
function getKey()
{
return time() . rand(0, 10000);//获取key值防止用户重复登陆
}
//存取key到缓存,并设置key的有效时间,判断key值是否变化
function cacheKey()
{
global $config;
$cache = getCache();
$key = getKey();
return $cache->set($key, -1, ['nx', 'ex' => $config['expire']]) ? $key : cacheKey();
}
function response($code, $msg, $data = [])
{
exit(json_encode(compact('code', 'msg', 'data')));
}
//获取缓存,用来存储key值
function getCache()
{
static $cache;
return $cache ?? $cache = \Symfony\Component\Cache\Adapter\RedisAdapter::createConnection('redis://localhost');
}
//根据微信的app_id,secret获取app值
function getWechatApp()
{
global $config;
static $app;
return $app ?? $app = \EasyWeChat\Factory::officialAccount([
'app_id' => $config['app_id'],
'secret' => $config['secret'],
]);
}
if ('getQrcode' == $type) {
try {
$key = cacheKey();
$app = getWechatApp();
$result = $app->qrcode->temporary($key, $config['expire']);//根据key值和二维码有效时间生成临时二维码
$url = $app->qrcode->url($result['ticket']);//将临时二维码是指为地址
$data = ['key' => $key, 'url' => $url];//输出key值和二维码地址
response(0, 'success', $data);
} catch (Exception $e) {
response(500, '系统繁忙,请稍后再试');
}
}
if ('login' == $type) {
$con = getCon();
$result = mysqli_query($con, "select openid from users where id=1");
$user = mysqli_fetch_assoc($result);
// response(0, '已登陆',$user);
if($user){
$result = mysqli_query($con, "delete from users where id=1");
response(0, '已登陆',$user);
}else{
$result = mysqli_query($con, "delete from users where id=1");
response(-1, '未登陆',$user);
}
// $key = $_GET['key'];//获取当前的key值
// $cache = getCache();//获取缓存
// $userId = $cache->get($key);//判断缓存中的key值是否与当前key值相等
// if (-1 == $userId) {//不相等显示未登录
// response(-1, 'not login',$userId);
// } elseif (!$userId) {//没有值显示过期
// $con = getCon();
// $result = mysqli_query($con, "select openid from users where id=1");
// $user = mysqli_fetch_assoc($result);
response(0, '已登陆',$user);
// if($user){
// $result = mysqli_query($con, "delete from users where id=1");
// response(0, '已登陆',$user);
// }else{
// response(1, '二维码已经过期',$userId);
// }
//
// } else {//存在即此时的id值为数据库查询到的id值
// session_start();
// $_SESSION['userId'] = $userId;
// response(0, '已登陆',$userId);
// }
}
if ('autoLogin' == $type) {
$con = getCon();
$result = mysqli_query($con, "select openid from users where id=1");
$user = mysqli_fetch_assoc($result);
// response(0, '已登陆',$user);
if($user){
$result = mysqli_query($con, "delete from users where id=1");
response(0, '已登陆',$user);
}
// response(-1, 'no login',$openId);
// $con = getCon();
// if (!$userId || !$result = mysqli_query($con, "select id,nick_name,avatar_url from users where id=$userId")) {
// response(-1, 'no login');
// }
// $user = mysqli_fetch_assoc($result);
// response(0, 'success', [
// 'userInfo' => [
// 'nickName' => $openId,
// ]
// ]);
}
function responseMsg()
{
$postStr = file_get_contents("php://input");//获取数据流
if (!$postStr) {
exit();
}
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);//将数据流转化成字符串类型
$msgType = trim($postObj->MsgType);//判断事件类型
if ('event' == $msgType) {
//判断是关注和扫码事件
echo receiveEvent($postObj);
}
}
function getCon()
{
static $con;
return $con ?? $con = mysqli_connect('localhost', '数据库账号', '数据库密码', '数据库名称');
}
function loginInit($key, $openId)
{
$cache = getCache();
// if (!$cache->exists($key)) {
// return false;
// }
$con = getCon();
$result = mysqli_query($con, "insert into users(openid,id)values ('$openId',1)");
// if (!$result) {
// try {
// $app = getWechatApp();
// $user = $app->user->get($openId);
// } catch (Exception $e) {
// return false;
// }
// $nickname = $user['nickname'];
// $avatarUrl = $user['headimgurl'];
// $result = mysqli_query($con, "insert into users(nick_name,avatar_url,openid)values ('$nickname','$avatarUrl','$openId')");
// if (!$result) {
// return false;
// }
// $uid = mysqli_insert_id();
// }
$user = mysqli_fetch_assoc($result);
$uid = $user['openid'];
return true;
}
function transmitText($postObj, $content)
{
$xmlTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
return sprintf($xmlTpl, $postObj->FromUserName, $postObj->ToUserName, time(), $content);
}
function receiveEvent($postObj)
{
if (in_array($postObj->Event, ['subscribe', 'SCAN'])) {
$key = str_replace('qrscene_', '', $postObj->EventKey);//获取数据流传输过来的事件类型
if (empty($key)) {
//若没有返回空值
return '';
}
//若接收到则调用登陆判断
$responseText = loginInit($key, trim($postObj->FromUserName)) ? '登陆成功' : '系统繁忙,请稍后再试';
return transmitText($postObj, $responseText);
}
return '';
}
if ('notify' == $type) {
// loginInit(123, osUsv5gncfksgUo1Nn8AnO9mJa88);
responseMsg();
// response(1, '二维码已经过期');
//echo $_GET['echostr'];
}
eg:有一点忘记提了,你还需要在在宝塔面板上建立一个数据库,因为挺简单的,网上教程也多,这里就不具体叙述了,数据库的大概样子如下
![在这里插入图片描述](https://img-blog.csdnimg.cn/5ca44fd01dc0467c9d7f043690a1daf0.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/6f5141008ae14d878b65c06c6da811c5.png)
sql文件点此链接获取
注:数据库导入后按照上面图片对数据库进行结构,编辑因为改版后已经不支持获取用户头像和昵称了
这里有具体测试php代码的方法(可以查看二维码是否调用):点此此处
三、vue的前端调用
注:在调用前忍不住吐槽一下内心的想法,原本想利用微信登陆获取头像和昵称的,但是微信为了用户的安全性在2021年12月取消了该权限,所以最终只能获取到用户的openid了,具体文件如下所示!!!
这里前端代码太多,就直接给出vue前端源码吧
源码链接:点击此处
总结
做了一次微信登陆,感觉特别繁琐,最后也没有获取到用户的头像和昵称,没有达到最后的预期,虽然最后通过网页授权的方法实现了,但是接口始终不是自己的,所以把自己的经历给写下来分享给大家。