微信公众号用户与网站用户的绑定方案

原文地址:http://hello1010.com/bind-wechat/

现在很多网站都已经建立了一套完整的用户账号体系,基于这套账户信息,再做其他应用的用户扩展就非常方便。例如,有了微软的outlook账户,就可以登录win8,可以登录微软的邮箱,还可以登录skype。同样地,一个Apple ID可以享受苹果的所有服务。正所谓,一个账号,处处使用。

对于企业,可能会有产品线通常有网站,app,微信公众号等。统一各产品线的账号体系,实现一个账号处处使用的目标是非常有必要的。网站和app使用同一个账号,不需要做任何多余的工作,客户只要有用户名密码即可登录。对于微信公众号,由于它是基于微信公众平台的一个应用,需要遵守平台的规则,所以需要做一些额外的工作才能达到账号互通的目标。

接下来我们就来讨论一下,如何做到微信公众号用户与网站用户的账号体系无缝对接。

当用户关注微信公众号后,会有一些交互,交互过程中可能需要获取到用户的身份信息(对应到网站的账户信息),例如在公众号中下单,查询订单等操作。那么现在问题来了:对于同一个用户,我们如何建立微信公众号用户(openid)与网站用户(userid)之间的对应关系。这个过程我们称之为绑定。


为了简化讨论,我总结了这样两个场景:

一、用户已注册成为我们的网站用户,但还未关注我们的微信公众号; 
二、用户未注册,但已关注我们的微信公众号。

对于以上两种情况,下面分别讨论。

场景一

用户已注册成为我们的网站用户,但还未关注我们的微信公众号。如何方便用户关注公众号,同时又能把用户和微信公众号绑定在一起呢?很自然地就可以想到二维码这个入口。

最近几年,二维码的应用特别广泛。微信对二维码的推广及应用可以说是如鱼得水,微信二维码支付,微信二维码登录,微信二维码名片等等。可以说,二维码已经成为O2O中连接线上线下的重要纽带。小马哥也称"二维码是线上线下的一个关键入口"。


在这里,需要用户在网站上先登录,然后在合适的地方给出一个绑定入口,比如在个人设置里。绑定流程如下:


这里需要用到微信的二维码生成功能:生成带参数的二维码

关于微信二维码,官方文档中这样说:

目前有2种类型的二维码,分别是临时二维码和永久二维码,前者有过期时间,最大为1800秒,但能够生成较多数量,后者无过期时间,数量较少(目前参数只支持1--100000)。两种二维码分别适用于帐号绑定、用户来源统计等场景。

显然,我们使用临时二维码比较合适。每当用户刷新页面时,都可以生成一次。

由于二维码里可以带有场景值(scene_id),当用户扫描带有场景值的二维码后,微信服务器会把场景值推送给我们自己的服务器,我们拿到场景值后,就可以做验证和绑定逻辑。注意:生成二维码需要认证后的服务号。

一次完整的绑定流程应该是这样的:

①用户登录网页,点击“绑定微信账户”; 
②后台使用微信接口,生成二维码链接返回给前端显示,并建立场景值A与用户的对应关系; 
③用户扫描二维码,并点击关注微信公众号(假如已关注,直接跳到④); 
④后台接收微信服务器推送的场景值A; 
⑤后台根据场景值A,查询到对应的用户ID(依赖于②中建立的对应关系); 
⑥建立用户userid与微信用户openid的对应关系; 
⑦给用户的微信客户端推送“绑定成功”的提示; 
⑧通知前台页面,绑定已完成,刷新页面,并返回一些微信账户信息。完成绑定。

其中,②中,“建立场景值A与用户之间的对应关系”,因为用户已经登录,所以用户点击“绑定微信账户”时,我们可以在后台分配一个临时场景值A与用户ID之间的对于关系。对于用户量不大的网站,可以直接使用php中的apc来缓存,并设置一个过期时间(与临时二维码过期时间设置成一样即可)。

⑧中,因为http没有推送机制,所以最简单的方法就是轮询去查询,是否已经完成绑定,完成绑定后再刷新页面。

完成绑定后,用户再跟我们的微信公众号交互时,根据openid可以找到对应的userid,即完成身份识别。对于之前提到的下单,查询订单,都是可以实现的。

整个绑定过程并不复杂,实现起来也没有太大的技术难度,最关键的是思路。

场景二

场景二,对于用户来说操作略微复杂,因为它需要用户在微信客户端的网页中完成登录/注册。所以,假如注册过程太过复杂繁琐,不建议使用。

流程:


上述绑定流程集成了注册的过程,所以看起来比较复杂。实现起来也没有太大的难度,我们重点关注一下安全性方面的问题,因为绑定账户涉及到用户的信息安全,考虑两个问题:

1、如何防止链接被伪造

登录/注册的链接需要确保是我们自己的服务器生成的,其他人无法伪造。可以参考微信的验证服务器地址的有效性。所以一个比较安全的登录链接可以是这样的:

http://api.hello1010.com/wechat/login.html?openid=x1&signature=x2&timestamp=x3&nonce=x4&echostr&=x5

校验签名的代码:

private function checkSignature()
{
    $signature = $_GET["signature"];
    $timestamp = $_GET["timestamp"];
    $nonce = $_GET["nonce"];    

    $token = TOKEN;
    $tmpArr = array($token, $timestamp, $nonce);
    sort($tmpArr, SORT_STRING);
    $tmpStr = implode( $tmpArr );
    $tmpStr = sha1( $tmpStr );
    if( $tmpStr == $signature ){
        return true;
    }else{
        return false;
    }
}

token值可以跟自己的微信公众号后台的一致,也可以换一个,建议换一个安全点。

2、如何确保openid是可信的

考虑这种场景:A用户进入登录页面,复制登录链接到浏览器,把openid替换为B用户的openid,使用A用户的账号密码登录。这样就把A用户的userid和B用户的openid绑定在一起了,显然是不安全的。

解决方案有很多,比如可以给openid加密,在加密方法保密的情况下,用户无法伪造加密后的openid。假如不想给openid加密,可以在生成链接时,在服务器端建立openid与签名signature的对应关系,假如用户篡改了openid就无法通过校验。

记住,永远不要轻信客户端传过来的信息。

扩展应用

完成绑定后,我们可以做一些简单的应用。比如,公司需要举办一个线下路演活动,该活动需要报名才能参加,并且需要签到。

这是一个典型的可以用微信实现的O2O例子。流程如下:


其中,“绑定用户子流程”就是场景二中的流程。报名的交互在这里不再累述,每个业务都不一样。

对于一个已经完成绑定的用户,他参加一个活动,需要做的就是通过微信报名,然后扫描二维码签到,体验相当流畅。

如有任何问题,欢迎跟我交流!


微信公众号智能绑定实例,具体参考文章:http://blog.youkuaiyun.com/omsvip/article/details/39011263 微信公众号智能绑定功能所有的步骤都是以模拟实现的。 1.模拟打开微信公众帐号登录页面; URL地址:https://mp.weixin.qq.com/ 2.读取自己微信公众帐号的用户名和密码; 此处用户名和密码可以持久化到内存,文件,数据库,缓存中都可以,因为在此操作过程中需要多次验证。 3.配置微信公众号接入的URL和Token; 此处可以和步骤2一样选择持久化。(持久化可以应对多个微信公众帐号操作) 4.模拟微信公众号成功登录; 此处有时候因网络原因需要重试几次。 5.设置开发模式,服务器回调; 成功建立连接,启用开发模式此处模拟提交URL和Token。 6.完成步骤5后,在开发者页面读取AppId和AppSecret让其持久化; 此处根据请求到的页面代码,可以使用正则表达式或者使用:Document、Elements 对象定位AppId和AppSecret的位置,便于获取值。 7.在微信公众号设置页面,获取微信公众号信息持久化到数据库中; 如:公众号名称,原始帐号ID,公众号头像及二维码(此处头像可以下载保存到自己的服务器中),公众号类型等。 8.成功完成以上步骤后,可以根据自己的需求调用微信相关API获取数据。 a.获取粉丝信息持久化到数据库中。 b.创建自定义菜单。 说明:因为此处模拟人工操作,后期微信页面布局及页面相关属性变化,则智能绑定功能会失效,此时需要修改步骤5、7的内容。 如果后期微信公众号登录只能通过扫描二维码登录则智能绑定功能完全失效,目前企业号使用的就是扫描二维码+密码登录方式。
<think>我们正在讨论微信小程序用户微信用户绑定的数据库设计方案。根据引用[1],我们知道微信开发者工具提供了开发、调试等功能,但并未直接给出数据库设计方案。因此,我们需要从实际业务需求出发设计数据库。 微信小程序用户微信用户绑定通常指的是:一个小程序用户(在小程序内注册或使用的用户一个微信用户(通过微信开放平台或微信登录体系识别的用户)建立关联。这种绑定关系通常通过微信的开放能力(如微信登录)实现。 设计方案要点: 1. 微信用户唯一标识:微信会为每个用户在同一小程序下生成唯一的OpenID,同一用户在不同小程序下OpenID不同。如果多个小程序关联在同一开放平台账号下,则可以通过UnionID来标识同一用户(同一用户在不同小程序下的UnionID相同)。 2. 小程序用户标识:在小程序内部,我们可能需要维护一套用户体系,例如为用户生成一个内部用户ID(user_id)。 因此,绑定关系可以设计为:将微信提供的OpenID(或UnionID)小程序内部用户ID进行关联。 数据库表设计(示例): 我们可以设计一张用户绑定关系表,例如`user_wechat_binding`,包含以下字段: - `id`: 主键,自增长。 - `user_id`: 小程序内部的用户ID,关联到用户表(user)的主键。 - `openid`: 微信用户在当前小程序的唯一标识(注意:一个用户在一个小程序只有一个openid,但不同小程序不同)。 - `unionid`: 微信用户在开放平台下的唯一标识(如果小程序绑定了开放平台,则会有unionid;否则可能为空)。同一用户在同一开放平台下的所有应用,unionid相同。 - `created_at`: 绑定时间。 注意:为了加速查询,我们可以在`openid`和`unionid`上建立索引。 具体流程: 1. 当用户通过微信登录小程序时,微信会返回用户的openid(以及session_key等),如果小程序绑定了开放平台且用户关注了同一开放平台下的公众号等,还会返回unionid。 2. 在小程序内部,我们可能有自己的用户注册流程。如果是新用户,则创建一条新的用户记录(在用户表里),同时将openid(和unionid)这个用户ID绑定;如果是老用户(通过openid或unionid能够找到绑定记录),则直接登录。 安全性: 由于openid和unionid是敏感信息,需要安全存储,避免泄露。 示例表结构(MySQL): ```sql CREATE TABLE `user_wechat_binding` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `user_id` bigint(20) unsigned NOT NULL COMMENT '小程序内部用户ID', `openid` varchar(64) NOT NULL DEFAULT '' COMMENT '微信用户在当前小程序的唯一标识', `unionid` varchar(64) NOT NULL DEFAULT '' COMMENT '微信开放平台下的唯一标识', `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `idx_openid` (`openid`), -- 一个openid只能绑定一个内部用户 KEY `idx_unionid` (`unionid`), -- 根据unionid查询 KEY `idx_user_id` (`user_id`) -- 根据内部用户ID查询 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信用户绑定关系表'; ``` 补充说明: - 一个微信用户(同一个openid)只能绑定一个小程序内部用户,所以openid字段设为唯一索引。 - 同一个用户(同一个unionid)可能绑定多个小程序内部用户(如果业务允许同一微信用户注册多个账号),但通常我们不希望这样,所以在业务逻辑上需要处理:如果发现同一个unionid已经绑定了其他内部用户,可以提示用户是否进行账号合并或直接登录已有账号。因此,unionid不需要唯一索引,但需要索引便于查询。 - 另外,我们还需要一个用户表(user)来存储小程序内部用户的信息,例如用户名、手机号等,这里不展开。 绑定流程代码逻辑(伪代码): ``` 用户点击微信登录 -> 小程序调用wx.login()获取临时code -> 将code发送到开发者服务器 -> 开发者服务器使用code向微信接口服务换取openid和session_key(以及unionid) -> 检查绑定表中是否有该openid(或unionid)的记录: 如果有,则获取对应的user_id,并登录该用户。 如果没有,则创建新的用户(在user表中插入记录),并在绑定表中插入新的绑定记录。 ``` 注意事项: 1. 如果小程序同时需要支持其他登录方式(如手机号登录),则需要在用户表中设计多种登录方式的关联,这里不展开。 2. 一个用户可能绑定多个微信账号?通常不允许,因为一个微信账号在同一小程序下的openid是唯一的,所以一个内部用户只能绑定一个微信账号(通过openid)。但是,一个内部用户可以有多个绑定记录(比如同时绑定微信和QQ)?这属于多账号绑定,需要另外设计。 以上是针对微信小程序用户微信用户绑定的数据库设计方案的基本思路。 生成相关问题: 1. 微信小程序登录的具体流程是怎样的? 2. 如何处理一个微信用户绑定多个小程序内部用户的情况? 3. 如何设计用户表以支持多种登录方式(微信、手机号、邮箱等)? 4. 在数据库中存储openid和unionid需要注意哪些安全问题? 5. 如何实现一个用户绑定多个第三方平台账号(例如同时绑定微信和QQ)? </think>### 微信小程序用户微信用户绑定的数据库设计方案 微信小程序用户微信用户绑定的核心是通过微信OpenID/UnionID建立关联。以下是推荐的数据库设计方案: #### 1. 核心表结构(MySQL示例) ```sql -- 小程序用户表 (存储小程序侧用户信息) CREATE TABLE `mp_users` ( `user_id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, -- 小程序内部用户ID `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `last_login` DATETIME NOT NULL, PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 微信绑定关系表 (核心关联表) CREATE TABLE `wechat_bindings` ( `bind_id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `user_id` BIGINT UNSIGNED NOT NULL, -- 关联mp_users.user_id `openid` VARCHAR(32) NOT NULL, -- 微信用户唯一标识 `unionid` VARCHAR(32) DEFAULT NULL, -- 跨应用统一ID(可选) `session_key` VARCHAR(24) NOT NULL, -- 微信会话密钥 `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`bind_id`), UNIQUE KEY `uniq_openid` (`openid`), -- 唯一索引 KEY `idx_unionid` (`unionid`), -- 联合索引 FOREIGN KEY (`user_id`) REFERENCES `mp_users`(`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` #### 2. 关键字段说明 | 字段 | 说明 | |--------------|----------------------------------------------------------------------| | `openid` | 用户在当前小程序的唯一标识(长度28字符) | | `unionid` | 微信开放平台统一ID(需绑定开放平台账号)长度同上 | | `session_key`| 微信登录会话密钥(需加密存储) | | `user_id` | 小程序内部用户体系主键 | #### 3. 绑定流程设计 1. **前端授权**:小程序调用 `wx.login()` 获取临时code 2. **后端交换**:服务端用code向微信接口换取`openid`和`session_key` $$ \text{code} \xrightarrow{\text{微信API}} \{\text{openid}, \text{session\_key}\} $$ 3. **绑定决策**: - 若`openid`存在 → 直接登录关联账号 - 若不存在 → 创建新用户并建立绑定 #### 4. 安全设计要点 1. **敏感数据加密**: ```python # 示例:AES加密session_key from Crypto.Cipher import AES def encrypt_session(key, session_key): cipher = AES.new(key, AES.MODE_GCM) ciphertext, tag = cipher.encrypt_and_digest(session_key) return ciphertext + tag ``` 2. **访问控制**: - 绑定接口需验证小程序来源(AppID鉴权) - 每次请求携带登录态token验证身份 3. **数据隔离**: - 生产/测试环境使用不同数据库实例 - 敏感操作记录审计日志 #### 5. 性能优化建议 - 读写分离:绑定查询走从库 - 缓存设计:OpenID → UserID 映射关系缓存 - 索引优化:确保`openid`字段唯一索引 > 注意:UnionID需要将小程序绑定微信开放平台账号才能获取,用于同一用户在多个微信应用间的身份贯通[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值