yfsns/laravel-wechat-login

微信登录驱动 - 支持微信扫码登录、移动端一键登录和OAuth授权

Maintainers

Package info

github.com/axing189/laravel-wechat-login

pkg:composer/yfsns/laravel-wechat-login

Statistics

Installs: 4

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v2.1.0 2026-03-03 11:02 UTC

This package is auto-updated.

Last update: 2026-03-31 11:11:42 UTC


README

微信登录驱动,实现了 YFSNS 系统的第三方登录驱动接口,支持微信扫码登录和 OAuth 授权。

功能特性

  • ✅ 微信扫码登录(Web端)
  • ✅ 微信移动端一键登录
  • ✅ OAuth 授权登录
  • ✅ 实现统一的第三方登录驱动接口
  • ✅ 使用主应用的 social_accounts
  • ✅ 无需额外的数据库迁移
  • ✅ 简单的安装和配置

安装

1. 安装 Package

composer require yfsns/laravel-wechat-login

2. 发布配置文件

php artisan vendor:publish --tag=config

配置

.env 文件中添加:

# Web端配置(扫码登录)
WECHAT_APP_ID=your_app_id
WECHAT_APP_SECRET=your_app_secret
WECHAT_REDIRECT_URI=https://your-domain.com/api/v1/social-login/wechat/callback
WECHAT_SCOPE=snsapi_login

# 移动端配置(一键登录)
WECHAT_MOBILE_APP_ID=your_mobile_app_id
WECHAT_MOBILE_APP_SECRET=your_mobile_app_secret
WECHAT_MOBILE_REDIRECT_URI=https://your-domain.com/api/v1/social-login/wechat/callback
WECHAT_MOBILE_SCOPE=snsapi_userinfo

配置说明

配置项 说明 默认值 必填
WECHAT_APP_ID Web端App ID -
WECHAT_APP_SECRET Web端App Secret -
WECHAT_REDIRECT_URI Web端回调地址 -
WECHAT_SCOPE Web端授权范围 snsapi_login
WECHAT_MOBILE_APP_ID 移动端App ID 使用Web端配置
WECHAT_MOBILE_APP_SECRET 移动端App Secret 使用Web端配置
WECHAT_MOBILE_REDIRECT_URI 移动端回调地址 使用Web端配置
WECHAT_MOBILE_SCOPE 移动端授权范围 snsapi_userinfo

授权范围说明

  • Web端

    • snsapi_login:扫码登录,只能获取用户openid
    • snsapi_userinfo:扫码登录,可以获取用户详细信息
  • 移动端

    • snsapi_base:静默授权,只能获取用户openid
    • snsapi_userinfo:弹出授权页面,可以获取用户详细信息(推荐)

使用

通过主应用的第三方登录接口使用

微信登录驱动会自动注册到主应用的第三方登录系统中,可以通过以下接口使用:

接口 说明
GET /api/v1/social-login/drivers 获取可用登录驱动列表
GET /api/v1/social-login/wechat/login 获取微信扫码登录 URL(Web端)
GET /api/v1/social-login/wechat/mobile-login 获取微信一键登录 URL(移动端)
GET /api/v1/social-login/wechat/callback 处理微信登录回调

前端调用示例

// 1. 获取可用驱动
fetch('/api/v1/social-login/drivers')
  .then(res => res.json())
  .then(data => console.log(data));

// 2. Web端:获取扫码登录 URL
fetch('/api/v1/social-login/wechat/login')
  .then(res => res.json())
  .then(data => window.location.href = data.data.login_url);

// 3. 移动端:获取一键登录 URL
fetch('/api/v1/social-login/wechat/mobile-login')
  .then(res => res.json())
  .then(data => window.location.href = data.data.login_url);

// 4. 处理回调(后端自动处理)

微信开放平台配置

Web端扫码登录

  1. 登录 微信开放平台
  2. 创建网站应用
  3. 获取 App ID 和 App Secret
  4. 设置授权回调域名

移动端一键登录

  1. 登录 微信开放平台
  2. 创建移动应用
  3. 获取 App ID 和 App Secret
  4. 设置授权回调域名
  5. 在微信开发者工具中测试

驱动接口实现

微信登录驱动实现了 App\Modules\Auth\Contracts\SocialLoginDriverInterface 接口:

interface SocialLoginDriverInterface
{
    public function getName(): string;
    public function getDriverType(): string;
    public function getLoginUrl(?string $state = null): string;
    public function handleCallback(string $code): array;
    public function getUserInfo(string $accessToken, string $openid): array;
    public function getConfigFields(): array;
    public function validateConfig(array $config): array;
    public function setConfig(array $config): void;
    public function getConfig(): array;
    public function testConnection(): array;
}

数据存储

微信登录驱动使用主应用的 social_accounts 表存储用户信息:

CREATE TABLE social_accounts (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    user_id BIGINT UNSIGNED NOT NULL COMMENT '关联用户ID',
    driver VARCHAR(50) NOT NULL COMMENT '第三方登录驱动',
    openid VARCHAR(255) NOT NULL COMMENT '第三方用户唯一标识',
    unionid VARCHAR(255) NULL COMMENT '第三方开放平台唯一标识',
    nickname VARCHAR(255) NULL COMMENT '第三方昵称',
    avatar VARCHAR(500) NULL COMMENT '第三方头像',
    data JSON NULL COMMENT '原始数据',
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,
    
    INDEX idx_user_id (user_id),
    INDEX idx_driver_openid (driver, openid),
    UNIQUE KEY uk_driver_openid (driver, openid),
    FOREIGN KEY fk_user_id (user_id) REFERENCES users(id) ON DELETE CASCADE
) COMMENT='第三方登录账号表';

扩展包开发指南

创建新的第三方登录驱动

参考 WeChatLoginDriver 实现 SocialLoginDriverInterface

<?php

namespace Your\Namespace\Drivers;

use App\Modules\Auth\Contracts\SocialLoginDriverInterface;

class YourLoginDriver implements SocialLoginDriverInterface
{
    protected array $config;

    public function __construct(array $config = [])
    {
        $this->config = $config;
    }

    public function getName(): string
    {
        return '你的驱动名称';
    }

    public function getDriverType(): string
    {
        return 'oauth2';
    }

    public function getLoginUrl(?string $state = null): string
    {
        $params = [
            'client_id' => $this->config['client_id'] ?? '',
            'redirect_uri' => $this->config['redirect_uri'] ?? '',
            'response_type' => 'code',
            'scope' => $this->config['scope'] ?? '',
            'state' => $state ?? md5(uniqid('', true)),
        ];

        return 'https://api.example.com/oauth/authorize?' . http_build_query($params);
    }

    public function handleCallback(string $code): array
    {
        $tokenData = $this->getAccessToken($code);
        return $this->getUserInfo($tokenData['access_token'], $tokenData['openid']);
    }

    public function getUserInfo(string $accessToken, string $openid): array
    {
        return [
            'openid' => $openid,
            'unionid' => null,
            'nickname' => '用户昵称',
            'avatar' => '用户头像',
            'data' => [],
        ];
    }

    public function getConfigFields(): array
    {
        return [
            [
                'key' => 'client_id',
                'label' => 'Client ID',
                'type' => 'string',
                'required' => true,
            ],
            [
                'key' => 'client_secret',
                'label' => 'Client Secret',
                'type' => 'string',
                'required' => true,
            ],
        ];
    }

    public function validateConfig(array $config): array
    {
        $errors = [];
        if (empty($config['client_id'])) {
            $errors['client_id'] = 'Client ID 不能为空';
        }
        return $errors;
    }

    public function setConfig(array $config): void
    {
        $this->config = array_merge($this->config, $config);
    }

    public function getConfig(): array
    {
        return $this->config;
    }

    public function testConnection(): array
    {
        return [
            'success' => true,
            'message' => '连接测试成功',
        ];
    }
}

在 ServiceProvider 中注册

<?php

namespace Your\Namespace;

use Illuminate\Support\ServiceProvider;
use Your\Namespace\Drivers\YourLoginDriver;

class YourLoginServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->mergeConfigFrom(
            __DIR__ . '/config/your-login.php',
            'your-login'
        );
    }

    public function boot()
    {
        if ($this->app->runningInConsole()) {
            $this->publishes([
                __DIR__ . '/config/your-login.php' => config_path('your-login.php'),
            ], 'config');
        }

        $this->registerDriver();
    }

    protected function registerDriver(): void
    {
        if (!$this->isInterfaceAvailable()) {
            return;
        }

        $this->app->singleton(YourLoginDriver::class, function ($app) {
            return new YourLoginDriver(config('your-login'));
        });

        if ($this->app->bound(\App\Modules\Auth\Drivers\Registry\SocialLoginDriverRegistryInterface::class)) {
            $registry = $this->app->make(\App\Modules\Auth\Drivers\Registry\SocialLoginDriverRegistryInterface::class);
            $registry->registerDriver('your-driver', YourLoginDriver::class);
        }
    }

    protected function isInterfaceAvailable(): bool
    {
        return interface_exists('App\\Modules\\Auth\\Drivers\\Registry\\SocialLoginDriverRegistryInterface');
    }
}

更新日志

v2.1.0 (2026-03-03)

  • ✨ 新增移动端一键登录支持
  • ✨ 新增 getMobileLoginUrl() 方法
  • ✨ 新增 getWebLoginUrl() 方法
  • ✨ 新增移动端配置选项(mobile_app_id, mobile_app_secret, mobile_redirect_uri, mobile_scope)
  • ✨ 支持独立的 Web 端和移动端配置
  • 📝 更新文档,说明移动端登录的使用方法

v2.0.0 (2026-02-24)

  • 🔄 重构为驱动模式
  • 🔄 删除独立的数据库迁移
  • 🔄 删除独立的控制器和服务
  • 🔄 使用主应用的 social_accounts
  • ✨ 实现统一的第三方登录驱动接口
  • ✨ 简化安装和配置流程

v1.0.0 (2025-01-01)

  • 初始版本发布
  • 支持微信扫码登录
  • 支持自动创建用户
  • 支持用户信息同步

贡献

欢迎提交 Issue 和 Pull Request!

许可证

MIT License

作者

YFSNS Team

支持

如有问题,请提交 Issue 或联系作者。