首页 小组 问答 话题 好文 素材 用户 唠叨 我的社区

[分享]ThinkPHP 实现微信订阅号登录网站

天启Lv.1普通用户
2024-08-22 20:06:41
0
53

要实现微信订阅号登录网站,我们需要创建一些控制器和模型,并使用ThinkPHP内置的功能来处理验证码的生成、存储以及验证。下面我将提供一个简单的示例来说明如何实现这一功能。

第一步:环境准备

确保你已经安装了ThinkPHP 6,并且已经配置好了一个基本的应用环境。此外,你需要安装一个用于处理微信消息的库,例如 overtrue/wechat 或者 easywechat。这里我们将使用 easywechat

第二步:安装 EasyWeChat

使用Composer安装EasyWeChat:

composer require overtrue/easywechat

第三步:配置 EasyWeChat

config 目录下创建一个名为 wechat.php 的文件,用于配置微信相关的参数:

// config/wechat.php
return [
    'app_id' => env('wechat.app_id'),
    'secret' => env('wechat.secret'),
    // 其他配置项...
];

第四步:创建控制器

创建一个控制器来处理登录流程。这里我们假设你已经有了一个用户模型 User 和一个用于存储验证码的表 login_verifications

<?php

namespace app\index\controller;

use think\facade\Request;
use app\common\model\User;
use app\common\model\LoginVerification;
use EasyWeChat\Message\Text;
use think\facade\Db;
use think\facade\Log;

class LoginController extends BaseController
{
    public function __construct()
    {
        parent::__construct();
        $this->wechat = \EasyWeChat\Factory::officialAccount(config('wechat'));
    }

    /**
     * 处理来自微信的消息
     */
    public function handleWechatMessage()
    {
        $response = $this->wechat->server->serve();

        if (!is_null($response)) {
            return $response;
        }
    }

    /**
     * 发送验证码给用户
     */
    public function sendVerificationCode()
    {
        $message = Request::post('msgtype');

        if ($message === 'text') {
            $content = Request::post('content');
            if (trim($content) === '登录') {
                $openid = $this->wechat->user->getOriginalIdentifier();
                $verificationCode = $this->generateVerificationCode($openid);

                // 发送验证码给用户
                $this->wechat->message->send(new Text([
                    'touser' => $openid,
                    'content' => '您的验证码为:' . $verificationCode,
                ]));

                // 返回响应
                return json(['status' => 'success', 'message' => '验证码已发送']);
            }
        }

        // 如果不是登录命令或者消息类型不正确
        return json(['status' => 'error', 'message' => '无效请求']);
    }

    /**
     * 验证用户提交的验证码
     */
    public function verifyCode()
    {
        $code = Request::param('code');
        $openid = Request::param('openid');

        $loginVerification = LoginVerification::where('openid', $openid)
            ->where('code', $code)
            ->where('expired_at', '>', time())
            ->find();

        if ($loginVerification) {
            // 清除验证码
            $loginVerification->delete();

            // 模拟登录成功
            $user = User::where('openid', $openid)->find();
            if (!$user) {
                // 创建新用户
                $user = new User(['openid' => $openid]);
                $user->save();
            }

            session('user', $user);

            return json(['status' => 'success', 'message' => '登录成功']);
        } else {
            return json(['status' => 'error', 'message' => '验证码错误或已过期']);
        }
    }

    /**
     * 生成验证码并保存到数据库
     *
     * @param string $openid
     * @return string
     */
    private function generateVerificationCode($openid)
    {
        $code = str_pad(mt_rand(1, 999999), 6, '0', STR_PAD_LEFT);
        $expiredAt = time() + 300; // 5分钟过期

        $loginVerification = new LoginVerification([
            'openid' => $openid,
            'code' => $code,
            'expired_at' => $expiredAt,
        ]);
        $loginVerification->save();

        return $code;
    }
}

第五步:创建模型

创建两个模型:UserLoginVerification。这里仅展示 LoginVerification 模型的示例。

<?php

namespace app\common\model;

use think\Model;

class LoginVerification extends Model
{
    protected $table = 'login_verifications';
    protected $autoWriteTimestamp = 'datetime';
    protected $createTime = 'created_at';
    protected $updateTime = 'updated_at';

    public function getExpiredAtAttribute($value)
    {
        return strtotime($value);
    }
}

第六步:路由配置

route 文件夹下的 index.php 中添加路由配置:

Route::rule('wechat', 'index/LoginController/handleWechatMessage');
Route::rule('sendVerificationCode', 'index/LoginController/sendVerificationCode');
Route::rule('verifyCode', 'index/LoginController/verifyCode');

第七步:前端页面

创建一个HTML页面来接收用户输入的验证码,并通过Ajax调用后端接口进行验证。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login with WeChat</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <h1>Login with WeChat</h1>
    <p>请扫描二维码关注公众号后发送 "登录" 获取验证码。</p>
    <img src="/path/to/qrcode.png" alt="WeChat QR Code">
    <form id="login-form">
        <input type="hidden" name="openid" value="openid_here">
        <label for="code">验证码:</label>
        <input type="text" name="code" required>
        <button type="submit">登录</button>
    </form>

    <script>
        $('#login-form').on('submit', function(e) {
            e.preventDefault();
            const formData = $(this).serialize();

            $.ajax({
                url: '/verifyCode',
                method: 'POST',
                data: formData,
                success: function(response) {
                    if (response.status === 'success') {
                        alert('登录成功');
                        window.location.href = '/dashboard'; // 替换为你的首页地址
                    } else {
                        alert(response.message);
                    }
                },
                error: function() {
                    alert('发生错误,请稍后再试');
                }
            });
        });
    </script>
</body>
</html>

上述代码只是一个基本示例,根据实际情况调整其中的逻辑。比如验证码的有效期、错误处理等方面。另外需要确保服务器已经配置好了微信公众号的回调地址,并且设置消息加密方式等细节。

天启
天启

61 天前

签名 : 大运河向南是我家   53       0
评论
站长交流