早睡早起,方能养生
Sleep early rise early, way to keep healthy

微信扫码关注公众号登录PC网站思路详解(||使用开放平台)

super
2021-07-14 17:53
views 8786

方案一:使用微信开放平台

 

1)具体实现方法请看我前两天的文章。

 

 

方案二:使用微信公众号

 

客户有一个PC端网站,想在网站加上扫码登录为公众号引流,怎么实现?使用第一种方法,扫码登录可以,但是引不了流啊。下面介绍如何使用微信公众号实现扫码登录网站。

 

1)首先,登录微信的管理平台 https://mp.weixin.qq.com

 

2)开发 - 基本配置 - 服务器配置,你想办法给启用咯

 

 

如果不知道咋启用就去百度搜搜去,记得之前写过如何启用的文章,可以翻翻找找 (服务器配置启用后,用户的关注,取关,发消息等等事件都会被微信服务器转发到你自己设置的URL上,需要你在处理后,返回给用户相应的信息,且自动回复,自定义菜单等都会失效)

 

3)开始写API (这 是 一 个 划 水 的 标 题)

 

4)生成登录二维码(使用微信带参数的二维码功能来实现)

 

use EasyWeChat\Factory;

// 创建登录二维码
public function createMpLoginQrCode()
{
    $ip = Request::ip();

    $id = self::createID($ip);

    $config = [
        'app_id'    => '你的app id',
        'secret'    => '你的app srcret',
    ];

    $app = Factory::officialAccount($config);
    $result = $app->qrcode->temporary($id, 600); // 生成临时二维码 有效时间10分钟,这里是秒数,可以自己修改,临时最高为1个月
    if (!isset($result['ticket'])) error('二维码请求失败,网络繁忙');
    $url = $app->qrcode->url($result['ticket']);

    $content = file_get_contents($url); // 得到二进制图片内容
    success(['qrcode' => base64_encode($content), 'id' => $id]);
}

private function createID($ip)
{
    $id = md5(time() . $ip . rand(0, 999));
    if (Cache::has($id)) {
        return self::createID($ip);
    }
    return $id;
}

// 查询登录结果
public function getLoginResult()
{
    $id = input('id') ?? error('参数错误:id');
    if (Cache::has($id)) {
        success(Cache::get($id));
    }
    success(['status' => 0]);
}

 

注意:

API返回的二维码是base64的,需要前端加个base64图片头 jpg png都行

ID是前端请求扫码状态的唯一依据,需要前端页面每隔1秒 查询一次登录结果

 

5)处理微信服务器通知

 

<?php

namespace app\index\controller;

use EasyWeChat\Factory;
use think\Db;
use think\facade\Cache;

class Wechat
{
    // 这里是你设定的微信扫码通知URL
    public function index()
    {
        $config = [
            'app_id'    => '你的app id',
            'secret'    => '你的app secret',
            'token'     => '你的服务器配置的 token',
            // 'aes_key'   => '你的 aes_key ,如果服务器配置 是非明文模式,这个需要填上',
            'response_type' => 'array',
        ];

        $app = Factory::officialAccount($config);

        $app->server->push(function ($message) {
            switch ($message['MsgType']) {
                case 'event':
                    self::event($message);
                    return '欢迎关注super!';
                    break;
                default:
                    return '欢迎关注super!';
                    break;
            }
        });

        $response = $app->server->serve();
        $empty = strpos($response, '<Content></Content>');
        $success = strpos($response, 'success');
        if (!$empty && !$success) {
            return $response;
        } else {
            echo '';
        }
        exit;
    }

    public function event($data)
    {
        $event = $data['Event'];
        $open_id = $data['FromUserName'];
        switch ($event) {
            case 'subscribe':
                $id = explode('_', $data['EventKey'])[1];
                self::userLogin($open_id, $id);
                break;
            case 'unsubscribe':
                break;
            case 'SCAN':
                self::userLogin($open_id, $data['EventKey']);
                break;
        }
    }

	// 这里的$id 是咱们在第4步生成的id(用来请求登录状态那个),它通过微信的二维码带过来了,是贯穿全局的唯一标识
    public function userLogin($open_id, $id)
    {
    	// 查询用户是否注册
    	$user_info = Db::name('users')
                    ->where('open_id', $open_id)
                    ->field(['user_id'])
                    ->find();
		if ($user_info) {
			// 修改缓存内容,前端获取登录结果
            Cache::set($id, ['status' => 1, 'user_id' => $user_info['user_id']]);
        } else {
            $array = [
                'type' => 1,
                'open_id' => $open_id,
                'reg_time' => time()
            ];

            $user_id = Db::name('users')->insertGetId($array);
            if ($user_id) {
            	// 修改缓存内容,前端获取登录结果
                Cache::set($id, ['status' => 1, 'user_id' => $user_id]);
            } else {
            	// 修改缓存内容,前端获取登录结果
                Cache::set($id, ['status' => 2, 'msg' => '网络繁忙,请稍后重试']);
            }
        }
    }
}

 

6)业务场景区分

 

vue:其实可以在最后一步中 生成token 存到缓存里面,而不用返回user_id,前端页面在拿到token后直接存进本地存储

 

普通html:在前端拿到user_id(或者可以生成一个随机不重复的秘钥,存到user表里面,不直接返回给前端user_id)后,可以跳转一个中间页,user_id作为参数找到用户信息把session存上,然后再进行刷新操作。

但是这样风险太高,用户网速过慢就能清楚的看到中间页地址栏中的user_id,那恰好这个叼毛是一个程序员,特意在控制台中调慢网速,截图记录你的中间页路由,那么他就可以使用路由+user_id随意的登录了,user_id试个遍想登谁的登谁的。这样肯定是不安全的,所以说,还是不建议直接返回user_id,在最后一步生成一个不重复的秘钥,跳转到中间页的时候,参数也使用秘钥去查用户信息,然后再存session,秘钥长一点不容易试出来。

 (咳咳,如果你觉得这个文章有用,标题和文章正文中间的那什么,帮忙点一下啦,好兄弟gkd)



分享
0 条讨论
top