童话说说技术创业美文职业
投稿投诉
职业母婴
职场个人
历史治疗
笔记技能
美文纠纷
幽默家庭
范文作文
乐趣解密
创业案例
社会工作
新闻家居
心理安全
技术八卦
仲裁思考
生活时事
运势奇闻
说说企业
魅力社交
安好健康
传统笑话
童话初中
男女饮食
周易阅读
爱好两性

搞定微信生态内的账户体系,看这篇文章就够了

6月6日 遭人厌投稿
  笔者从私域流量出发,论述了不同的业务和场景下如何处理微信私域相关的用户数据,并分享了自己的操作建议。
  最近私域流量的概念非常火,所谓私域流量,就是你可以自由反复利用,无需付费,又能随时触达,被沉淀在公众号、微信群、个人微信号、头条号、抖音等自媒体渠道的用户。相对淘宝、京东、百度这些公域流量平台,它属于商家私有资产。
  大家应该都在微信内用过小程序或者打开过网页,是不是经常发现会弹个窗,要求授权,然后网页上面就可以展示自己的微信头像和昵称了?这个其实就是微信通过接口给开发者提供的识别用户的能力。
  做私域流量,就会不可避免地涉及到一个问题,说用户进入了自己的私域,但是我们真的能认识用户吗?我们能成功地识别这个用户,并且展示该给这个用户展示的数据吗?微信的openid和unionid机制其中的复杂内容又有多少人知道呢?我们有很好地利用微信给我们提供的这些机制吗?抖音到底是怎么利用这些接口拿到用户的关系链的呢?
  我在网络上搜了很多相关的资料,有一些机制性质的描述,但是非常完整的剖析这个事情,并且做详细最佳实践分享的文章比较少,而且大部分都是从接口角度去分析这个东西。正好最近接触这块内容,就总结了一下,希望帮助后来的人少踩几个坑。
  在写这篇稿子的时候,我也考虑到可能不同公司的阶段不同,理论上功能开发要求应该不太一样,所以这篇稿子会论述不同的业务和场景下如何处理微信私域相关的用户数据,希望能抛砖引玉。
  一、基础概念知多少
  对用户做身份识别和权限限制,本质上是一个用户中心做的事情,计算机系统发展的历史有很久了,古往今来,凡是涉及到用户中心的系统,目的无外乎两个:
  一是身份识别,能够准确认识这个用户是谁,不会出现来一个用户,系统明明应该认识TA,但是完全不认识,也不会认错用户,不会把这个用户当成别的人,也不会把别人当成这个用户,也不会允许有人冒充这个用户。最好能够实现物理用户与虚拟账户的一一对应的关系。(在这里不考虑小号的情况)
  二是限权,用户相关的数据可以全部连带展示,不会丢数据,也不会展示不该展示的数据,不会出现越权的现象。
  好的用户体系主要就是做两个事情,身份识别和限权。所以下文所有的内容,都是围绕身份识别和限权这两个底层需要去做的。所有系统做的迭代和改进都只有一个目的如何让用户身份识别的成本降到最低,如何让系统限权做的最准确。上面这段话是整个用户中心设计的核心思想,如果想要打造一个靠谱的用户中心,就务必牢记这些内容。
  在正式开始进行最佳实践的探索之旅之前,不妨先简单的了解一下如下几个接口。
  1。微信网页授权(针对用户在微信内打开对应网页)
  https:mp。weixin。qq。comwiki?idmp1421140842
  在用户端的授权弹窗样式如下图所示:
  2。获取用户列表(针对已经关注了公众号的用户)
  https:mp。weixin。qq。comwiki?idmp1421140840
  3。小程序获取用户信息接口(针对访问小程序的场景)
  https:developers。weixin。qq。comminiprogramdevapiopenapiuserinfowx。getUserInfo。html
  在用户端的授权弹窗样式如下图所示:
  4。移动应用微信登录接口(针对App内利用第三方登录访问微信的场景)
  https:open。weixin。qq。comcgibinshowdocument?verify1idopen1419317851langzhCN
  在用户端的授权弹窗样式如下图所示:
  上述4个接口,分别是微信针对微信内浏览网页、已经关注公众号的用户、小程序和App提供的获取当前用户的微信相关信息和唯一标识的接口。
  四个接口(除了第二个)的流程都会涉及用户授权,用户也可能会拒绝授权,微信的官方文档经常会说一句屁话,就是开发者需要妥善处理用户拒绝的情况,但是从来没说过怎么妥善处理。
  四个流程的用户端的交互流程不太一样(主要是授权弹窗的样式和唤起环境不太一样,我觉得各位应该都见过),但是大体都是必须经过用户的授权(非静默),开发者才能拿到比较关键的信息,比如昵称、头像、unionid一个非常重要的唯一标识。
  有的人可能会问,为什么我一个开发者要搞4个接口?因为一个开发者有多个公众号,小程序和App,在微信看来都属于不同的应用,微信会给每个应用分配一个专属的Appid,不同的应用类型,接口自然是不同的。
  通过微信网页授权接口文档我们可以知道,微信会给我方系统返回如下参数:
  基于文档可以看到两个和id有关的字段,一个叫openid,一个叫unionid,这两个id是什么概念呢?都是id,有什么区别?
  微信官方的解释是这样的:unionid机制的作用说明:如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为同一用户,对同一个微信开放平台下的不同应用(移动应用、网站应用和公众帐号),unionid是相同的。
  也就是说,一个公司如果有一个小程序矩阵,同一个用户使用了这3个小程序,开发者能够从微信的接口获得到的数据一共有3条,3条数据用户的openid是不一致的,但是unionid是一致的,openid和unionid都是用户的唯一标示,但是二者唯一性的生成条件是不一致的。
  openid的唯一性用户微信号应用的appid(不同的公众号,小程序,appid都是不同的);
  unionid的唯一性用户微信号开发者主体(一般是公司)。
  值得一提的是,微信内的网页必须要挂靠一个公众号,所以微信网页授权获得的openid和对应挂靠公众号粉丝的openid是一致的。开发者可以选择将所有的网页都挂靠在一个公众号下面,这样可以减少授权弹窗的次数。
  总的来说,微信提供了很全面的生态系统,但是由于微信体系比较庞大,加上其设计理念比较保守,极端重视用户隐私(甚至有些偏执),会给开发者带来比较大的麻烦,所以想要正确地使用其实并不简单。
  此外,在下方的具体内容中,会涉及比较多的系统模块的描述,如果读者自己所在的公司还没有实施类似于微服务的架构,那么可能还需要对基础设施进行一些改造,但是核心思想也是可以套用的。
  二、单Appid场景的微信账户体系建设
  假设现在我们加入了一家初创公司,公司的业务非常简单,暂时不涉及到付费业务,只有一个小型的社区,提供一些评论,点赞和收藏的功能。目前只开通了一个公众号,那我们应该怎么设计针对微信的账户体系呢?我们该如何应用openid和unionid呢?
  基于上文提到的“用户体系的核心思想”既能够实现对于用户身份的精确识别,以及能够识别准确地读取该用户对应的数据,要做的事情就比较清晰了。一般在系统内都会生成一个userid,用来作为用户在系统内的唯一标示,同时业务方基于这个字段将用户和业务数据关联起来,实现限权。
  在微信体系内,unionid这个字段是可以被认定为识别用户的核心key,所以需要把userid和unionid做一个关联关系,总结下来,其实是要做如下几件事:
  快速精确身份识别要能够快速的辨识用户,用户识别要准确,不能出现把用户识别错误的情况,也不能出现明明应该认识但是却不认识的情况。交互层面,最好用户操作成本超级低,点一下,甚至不点就能识别;
  准确限权用户相关的数据可以全部连带展示,不会丢数据,也不会展示不该展示的数据。
  结合微信提供的接口能力,将上述目标进行翻译,其实要做的事情是这样的:
  核心机制一,将unionid和userid绑定实现限权把微信的unionid和自有系统的userid绑定起来,通常需要基于登录行为实现;
  核心机制二,利用openid进行快速身份识别由于微信内网页可以直接识别用户的openid,所以需要将openid和unionid做关联,来实现一种“长效并且精准的cookie”的效果,这样用户即使更换手机,只要不更改微信号,系统就永远能够以最低成本直接对其进行身份识别;
  核心机制三,交互层面处理用户拒绝授权妥善处理用户拒绝授权,所以拿不到unionid的情况。
  虽然我很讨厌微信这个“妥善处理”的说辞,但是在这种情况下,我真的不知道该怎么总结这项工作。
  核心机制一将unionid和userid绑定实现限权的逻辑比较简单,用户在微信内访问系统的页面,触发了微信网页授权的弹窗,用户同意授权后,系统拿到了该用户(该微信号)对应的unionid,然后把这个unionid和系统本身的的userid关联起来(比如先弹窗,然后要求用户基于手机号和短信验证码登录,也可以做静默注册,看具体业务),然后系统就会有一个【unioniduserid】的数据,两者一一对应。
  从此以后,用户只要通过微信环境访问系统系统,就自动种上数据库已经关联的对应userid的cookie,同时限制用户在别的微信号环境内再用这个userid进行登录操作。(场景举例:换个微信用相同的手机号尝试登录)
  核心机制二利用openid进行快速身份识别实现起来也不复杂,微信网页授权有一种机制叫做snsapibase为scope发起的网页授权,可以获取进入页面的用户的openid的,并且是静默授权。同时由于用户已经允许授权,所以系统拿到了【openidunionid】的关联关系,系统内的数据就变成了【openid(公众号A)unioniduserid】结构的数据。
  借助数据库里面的数据和snsapibase为scope发起的网页授权的机制,这个用户日后无论在天涯还是海角,只要在微信内打开网页,系统都能认识他。
  核心机制三交互层面处理用户拒绝授权,这个事情要处理起来会比较玄学,比较常用的做法是设定一个拦截机制。一般来说可以把强制要求授权弹窗的界面和强制要求登录的流程做在一起的,毕竟这两个性质是很相似的,说穿了就是两种不同的身份识别形式。
  哪些操作是必须是登录用户才能做的(比如下单购买、收藏、点赞、评论),就在对应的流程前面加上弹窗。微信网页授权弹窗是可以反复触发的,就和公司自己的开发写的原生登录弹窗一样,也可以在一进入页面的时候判断数据库内有没有对应的数据记录(openid相同的数据),如果没有就弹窗。
  如何具体地设计这些机制,需要产品经理根据自身业务和对转化率的敏感程度自行决定,如果老板觉得下单前拦截用户要求登录很蠢,也可以考虑去掉,但是这样就需要设计游客身份的机制,这个在下文会有更加详细的描述。
  上面三个核心机制就是做好公众号登录(微信网页授权)的核心逻辑,请各位同学如果要实践的话务必牢记。
  在数据存储方面,其实可以选择先存储openidunionid的关联信息,再根据用户后续登录的情况,存储unioniduserid的关联信息,具体的逻辑顺序会在下一小节的流程图之中描述中展现。
  当然有同学会问,为什么不可以通过snsapibase为scope发起的网页授权直接获取openid,然后和userid关联,为什么要因为获取不到unionid就做拦截呢?原因很简单,因为公司会发展,迟早会做小程序,做更多地业务,到时候回过头来再填这个坑,得不偿失。
  在拿不到unionid的情况下获取到的openid,只能作为前端用来给游客用户种cookie的手段,可以落库,给前端当cookie标识位使,但是不要落库到用户中心的数据库,否则后面填坑真的是火葬场,虽然会有两个填坑的小技巧就在下面,但是有条件不这么做的同学请务必不要这么搞。
  上面所有的设计都是理想情况,在现实生活中,我们还会遇到一些不理想的情况,比如程序员大哥忘记存unionid这个字段了。
  那怎么办?通过如下接口可以基于用户的openid再把unionid拿回来。
  接口地址:https:mp。weixin。qq。comwiki?idmp1421140839
  理论上来说,这个接口能够拿回来数据的,一定是因为用户做了下面几件事情:
  开发者帐号下存在同主体的公众号,并且该用户已经关注了该公众号。
  开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用。
  上面说的授权登录过该公众号其实就是指微信网页授权,这点要喷一下微信官方的文档,一个行为搞两个名词,其实挺烦人的。那么如果用户授权过同主体的小程序会是什么效果呢?官方文档没写,我也不敢乱说。
  这个方法不是万能的,假如用户已经把公众号取关了(备注:取关了再关注,openid和unionid不变),系统就拿不回信息了,然后数据库里面就会出现一堆unionid字段为空的数据,其实很蛋疼,所以说系统搭建这个事情,有的时候是一步错步步错。但是往往是业务初期,产品经理和开发都不是很在意,给后面人会造成很大的困扰,我会对这个机制如此了解,相信各位读者已经知道我之前踩了多少坑。
  如果用户已经取关,为了下次和用户再次相遇时可以拿回数据,就需要前端层面代码在做授权弹窗是否要弹的判断机制里面加上一条,该条openid对应的用户数据的unionid字段是否为空,如果为空,需要弹窗授权,拿回对应的unionid。
  三、多Appid场景的微信账户体系建设
  随着公司业务发展,之前的公众号做的不错,最近小程序风口正胜,公司也希望做一些变现的工作。老板说我们来做个小程序吧,然后再把咱们的电商给做起来,面对新的业务要求,用户中心该做出什么样的改进和变化呢?
  在这个情况下,我们肯定要先结构目标,如何在新增小程序的情况下做好系统的用户体系呢?其实说到底,还是要牢记设计用户中心时的核心思想,抽象下来就是要实现下面几个目标:
  快速精确身份识别要能够快速的辨识用户,用户识别要准确,不能出现把用户识别错误的情况,也不能出现明明应该认识但是却不认识的情况。交互层面,最好用户操作成本超级低,点一下,甚至不点就能识别。
  准确限权用户相关的数据可以全部连带展示,不会丢数据,也不会展示不该展示的数据。
  快速识别自动绑定由于有两个软件环境(微信网页和小程序),会涉及到两个环境下的用户数据的绑定与统一,由于会做电商,用户会对“数据丢失”非常敏感,所以用户数据的绑定就格外重要了。
  上面三点,一、二两点是固有的要求,第三点是涉及到了多Appid的情况之后新增的要求。
  结合微信提供的结果,把上面的目标翻译过来,就是下面几个核心要点:
  核心机制一,将unionid和userid绑定实现限权把微信的unionid和自有系统的userid绑定起来,通常需要基于登录行为实现
  核心机制二,利用openid进行快速身份识别由于微信网页可以直接识别用户的openid,所以需要将openid和unionid做关联,来实现一种“长效并且精准的cookie”的效果。
  核心机制三,利用openid进行快速身份识别(小程序场景)小程序也可以直接获取用户的openid,所以需要将openid和unionid做关联,来实现一种“长效并且精准的cookie”的效果。
  核心机制四,利用unionid与userid的绑定关系,实现快捷登录从小程序内获得的unionid和在微信网页内获得的unionid是一致的,所以二者其一如果在数据库已经建立了unionid和userid的关联数据,另一方应该可以借助数据库内的数据自动建立联系而不需要用户在做任何类似于手机号验证码登录的身份识别操作。
  核心机制五,利用unionid与userid的绑定关系,实现静默登录在某些特定情况下,小程序可以不通过用户授权直接获取unionid,所以应该要借助这个机制,帮助用户实现无需任何操作即可直接登录的效果。
  核心机制六,交互层面处理用户拒绝授权妥善处理用户拒绝授权,所以拿不到unionid的情况。
  核心机制一、二、三、六在上面一小节已经详细描述过就不多说了,我们就来着重说说上面核心机制四的和核心机制五。
  核心机制四和核心机制五的本质是一样的,本质上都是如下的流程:
  一定要说的话,核心机制四和核心机制五的最大区别就在上述流程图中的黄色区域部分。
  在一般情况下,我们需要弹窗请求用户的授权,才能从用户处获得openid和unionid的关联关系,否则就只能得到openid这一数据。特殊情况下,小程序环境内,可以通过接口直接获得用户的unionid和openid的关联关系,具体的描述见文档unionid获取途径:
  https:developers。weixin。qq。comminiprogramdevframeworkopenabilityunionid。html
  反过来说,如果用户是先在小程序做了登录,再访问微信内网页,也要做上面流程图内的操作,这样才可以最大成本的降低用户十分识别的成本,毕竟很多用户根本分不清小程序和微信内网页的区别是什么,在他们的认知里面,这个服务都是同一个公司提供的,理论上就应该可以自动可用,数据不能丢。
  说完了核心机制四和核心机制五,我再回过头来说核心机制一,虽然存在了2条数据,但是其实事情没有变复杂,只要自己不作死。
  在上面的一个小节里面,我们是如此描述绑定的逻辑的:
  用户在微信内访问系统的页面,触发了微信网页授权的弹窗,用户同意授权后,系统拿到了该用户(该微信号)对应的unionid,然后把这个unionid和系统本身的的userid关联起来(比如先弹窗,然后要求用户基于手机号和短信验证码登录,也可以做静默注册,看具体业务),然后我们就有一个【unioniduserid】的数据,两者一一对应。
  从此以后,用户只要通过微信环境访问系统系统,就自动种上数据库已经关联的对应userid的cookie,同时限制用户在别的微信号环境内再用这个userid进行登录操作。(场景举例:换个微信用相同的手机号尝试登录)
  其实这个逻辑核心做的事情是两个,第一个是把【unioniduserid】的这个关联关系数据存下来,二是做限制逻辑,保证二者是一一对应的关系。
  在加入了小程序之后,这个场景就产生了一些变化,因为unioniduserid这样的数据会出现两条,而且一定有先有后,所以后来的一条其实完全可以直接把先前一条的userid的数据填过来,就是上面流程图所描述的逻辑。即使一条数据变两条,事情本质是没有什么变化的。
  这里面就要格外强调,上面一个小节曾经提到过这样一个观点:
  在拿不到unionid的情况下获取到的openid,只能作为前端用来给游客用户种cookie的手段,可以落库,给前端当cookie标识位使,但是不要落库到【用户中心】的数据库。
  如果我们把unionid字段为空的数据落库到了用户中心的数据库会造成什么问题?不妨举个例子来说明。试下一下这样的场景:一个用户进入小程序,拒绝授权但是登录了手机号A,然后进入微信网页,也拒绝授权但是登录了手机号B,我们就会有如下数据。
  【openidAunionid为空useridA】
  【openidBunionid为空useridB】
  假如用户再来访问,在两个环境都允许授权了,会怎么样呢?数据库里面的数据就会被补全,变成如下的样子。
  【openidAunionidAuseridA】
  【openidBunionidAuseridB】
  问题来了,如果这个时候公司又开发了一个小程序,这个用户过来访问,允许授权,系统拿到了openidC和unionidA,那该把用户关联到哪个userid上面呢?所以我们可以看出来,如果unionid字段为空的数据落入了【用户中心】的数据是多么的麻烦,一旦牵扯到两个appid系统就立马歇菜了,非常容易出差错,但是如果unionid是不允许为空的,那么其实系统的逻辑依旧比较简单,而且很干净。
  如果有人不信邪觉得可以通过appid或者别的手段去关联,不妨可以试试,在线上运行一段时间,再去mysql里面跑数看看,百分百会遇到一个微信号关联两个userid的情况,这种时候用户再投诉订单丢失的问题,真的是跳进黄河也洗不清。
  除了逻辑层面的区别,和上面一小节里纯粹公众号场景处理的方式还有有一个比较大的区别,就是数据库里面理论上会存在这样的两条数据:
  【openid(公众号A)unioniduserid】
  【openid(小程序B)unioniduserid】
  我会建议把数据结构改造成下面这样的:
  【openid(公众号A)unioniduseridappidA】
  【openid(小程序B)unioniduseridappidB】
  为什么要增加appid的字段呢?原因比较简单,一会要做什么消息通知之类的功能,很多时候会基于appid这个字段做检索,加上去会很方便。
  很多时候一部分没什么经验的开发开发会喜欢用数字枚举值,比如公众号是1,小程序是2,但是实际上公司业务发展之后可能会做7,8个小程序,枚举值并不能很好地表达业务层面实质性的含义,这是种有问题的抽象方式,所以从一开始就把Appid存入系统中会比较科学。
  上面描述的逻辑其实已经很复杂了,单纯用文字描述不是很好懂,下面有一个流程图,各位可以抄作业了。需要强调的是,我所在的公司业务场景比这个还要再复杂一些,这个流程图里面的内容是没有在线上验证过的,所以这个流程图是无法保证100正确的。
  单独看流程图的话,也并不是非常好懂,所以我在6处地方做了tips,这6处的逻辑可能会有点绕,但是都是有非常明确地目的的,缺少其中的某一个步骤,会导致结果产生变动。
  【1】这个步骤做去重,主要是针对数据库很可能已经存在了一条一模一样的数据的情况,假如用户清除了cookie,前端不认识用户,就会把已有的数据传输过来,如果不做去重,下方逻辑判断会有问题。
  【2】这个情况如果完全按照上文的要求进行开发,理论上不会出现,但是由于开发不规范很可能会导致类似情况出现,所以特意加上这样的限制逻辑。
  【3】为了防止用户试图在别的微信号再次登录已经绑定了微信号的手机号而设计的机制。
  【4】再次去重的目的也比较简单,有可能先前数据库里面有数据【openidAunionidAuserid为空】,然后接口传过来【openidAunionidAuseridA】,第一次去重是不会把这两条数据当做重复数据的,但是经过上面的流程处理后,两条数据都会变为【openidAunionidAuseridA】,所以需要做去重逻辑。
  【5】将alpha写入数据库的时候,如果去重后还有数据readtime为空,说明这是全新的数据,需要直接insert,典型场景是用户第一次访问我方系统的服务。
  【6】这一步就是将最终结果返回给前端的过程,很可能前端只给后端openid和unionid,但是后端通过关联逻辑把userid也返回给了前端,前端就可以把cookie给种上了。
  上面这个流程,严格来说不是一个常规的登录流程,更像是一个数据绑定的流程,但是我建议所有涉及到微信用户体系的接口,全部封死成一个接口,不要分成绑定和登录两个接口。
  同时,所有涉及到常规登录的地方(比如App的账密登录),如果前端可以取到openid和unionid的value,都应该再调用一遍上面这个流程的接口。
  这么做的原因有三,一是因为这样做也可以实现业务的需求。二是为了减少测试的成本,通过上方的完整流程图就可以看出来其实上面的逻辑说这很简单,其实麻烦得很,如果再区分是绑定场景还是登录场景,测试起来会非常头疼。三是因为,从底层抽象来看,所谓的数据绑定本质是是利用用户无法伪造的openid来做了一个身份识别,其实也是一种登录,绑定就是登录的一种。
  接口的入参主要就是openid,unionid,userid三个要素,其中userid可以缺省,因为在核心机制四和核心机制五中提到的自动登录的场景下。我们还拿不到用户的userid,其实是把unionid传给服务端,服务端返回userid。
  四、涉及不登录生单的微信账户体系建设
  小程序上线了,用户数量激增,公司拿到了一笔融资,老板有点膨胀,说咱们做App吧。
  恰好,这时竞争对手的App也上线了,他们还支持一个非常吊的功能,就是游客身份也能直接生单购买,不需要在生单前登录,这时老板着急了,要求自家产品也要有一样的功能。
  首先,这是一个非常真实的背景,而且根据行业内知名电商公司的实践,有超过40的订单来源于游客生单,所以做的必要时有的,关键的点在于怎么做。在正式开始讨论方案之前,其实我们不妨再次再次回过头来看一下核心思想。
  用户体系要做的事情是什么?对用户进行身份识别,以及在身份识别的基础上进行限权操作。那么行业内常见的游客生单购买设计是不是和这个体系本身是相悖的呢?这个设计是不是太人格分裂了?我认为不是。
  因为无论是哪家公司,就算它对游客生单购买的支持做的再好,也仍然千方百计地在引导用户登录。本质是是因为游客生单购买这件事情其实是把App内的cookie当成了一种身份识别的唯一标示,而我们都知道cookie这种东西其实是很容易就会被抹掉的,如果用户用收集的垃圾清理功能清一下缓存,很可能就洗掉了,对应到用户端的感受就是找不到订单,这其实是比较严重的。
  需要注意的是,App内的微信授权和小程序微信内网页的微信授权,在交互上有比较大的差别。
  在小程序微信内网页获取openid时,可以通过类似于snsapibase为scope发起的网页授权直接获取openid,不需要用户做任何操作。
  在获取unionid时,也只是唤起微信环境内自带的控件(就是一个弹窗)向用户申请要求授权,交互流程是很简单的,而且任何页面或者任何按钮都可以加上这个触发,其实是非常方便的。
  在App内,想要获得用户的授权(这是唯一获得openid和unionid的方式)需要唤醒微信的App,然后用户在微信内授权后再返回开发者的App。这意味着这种唤醒操作不能像之前设计的时候那样随意地在任意节点插入,因为之前的环境内,发起授权不过是一个弹窗,阻断性会比较小,而在App内则会直接跳出App,交互上的代价会比较大,频繁弹出容易导致阻断主流程,得不偿失。
  一般建议将微信账户的授权做在登录界面处,引导用户绑定。也有一些在微信生态内玩的很溜的公司会选择在订单列表,我的等页面引导用户绑定,因为这些商家有很多用户都是从微信导流过来的,用户下载App之后第一反应肯定是我在微信里面下的单子跑哪里去了?。这样的设计可以很好地引导用户。
  上面说的都是交互层面的问题,在后端逻辑层面,App完成可以被当成另一个小程序或者公众号。
  说完微信在App内的授权,我们再说说游客生单购买是什么情况,游客生单购买的技术方案一般有两种。
  第一种是基于业务进行设计的游客生单购买,简单地说就是业务方的数据库允许在特定情况下,userid的字段为空。
  第二种方案是基于用户中心进行设计的游客生单购买,简单地说就是把游客的cookie当做身份的唯一标示,比如说利用cookie生成一个userid,传送给后端,然后等用户登录之后,用户中心再做替换,并且广播给业务方。
  无论是我自己所在的公司还是请教别的公司的产品经理,一般都认为第二种方案是更好地设计,扩展性会比较强,业务线不需要关心这么复杂userid替换的逻辑,可以直接拿过来用,比较符合小前台,大中台的设计理念,耦合性比较低。
  根据上面第二种方案的逻辑可以看出来,游客生单这件事情,其实在哪里都能做,大部分公司选择在App做是因为App的cookie保存时间一般会比浏览器久一些,用户不会没事去把App的缓存给清掉,风险相对可控。
  在讨论完本次系统改进的主要方案之后,让我们再回过头来看看这次系统设计的目标,我认为主要是下面的几个目标:
  快速精确身份识别要能够快速的辨识用户,用户识别要准确,不能出现把用户识别错误的情况,也不能出现明明应该认识但是却不认识的情况。交互层面,最好用户操作成本超级低,点一下,甚至不点就能识别。
  准确限权用户相关的数据可以全部连带展示,不会丢数据,也不会展示不该展示的数据。
  快速识别自动绑定由于有多个软件环境(微信网页、小程序、App等),会涉及到多个环境下的用户数据的绑定与统一,由于会做电商,用户会对“数据丢失”非常敏感,所以用户数据的绑定就格外重要了。
  产品导流后账户绑定相关的交互设计由于用户会很大概率先用小程序,再下载App,所以App在核心界面,可能需要引导用户绑定微信账户,这样才能同步数据。(比如用户在小程序以游客身份下单,但是同意了微信网页内授权,来到App的订单列表是看不到数据的,需要引导用户绑定微信账户)
  基于游客身份的自动绑定用户在多个微信环境以游客身份生单的关系关联问题,这时用户尽管没有登录,但是基于微信的机制我们仍然能够把他视为同一个人,所以需要做对应的措施。
  上面五点,一、二、三点是上文提到的固有的要求,四、五两点是基于新的业务场景提出来的新的要求。
  结合微信提供的接口,把上面的要求翻译成具体可执行的措施,就是下面几个核心要点:
  核心机制一,将unionid和userid绑定实现限权把微信的unionid和自有系统的userid绑定起来,通常需要基于登录行为实现
  核心机制二,利用openid进行快速身份识别由于微信网页可以直接识别用户的openid,所以需要将openid和unionid做关联,来实现一种“长效并且精准的cookie”的效果。
  核心机制三,利用openid进行快速身份识别(小程序场景)小程序也可以直接获取用户的openid,所以需要将openid和unionid做关联,来实现一种“长效并且精准的cookie”的效果。
  核心机制四,基于交互引导解决App内数据同步问题在App内基于微信授权的交互机制和用户的行为轨迹,在关键页面提示用户绑定微信账户。
  核心机制五,利用unionid与userid的绑定关系,实现快捷登录从小程序内获得的unionid,在微信网页内获得的unionid和App基于账户绑定获得的unionid是一致的,所以三者其一如果在数据库已经建立了unionid和userid的关联数据,剩余两方应该可以借助数据库内的数据自动建立联系而不需要用户在做任何类似于手机号验证码登录的身份识别操作。这个关联逻辑需要对游客身份生成的虚拟userid也同样生效。
  核心机制六,利用unionid与userid的绑定关系,实现静默登录在某些特定情况下,小程序可以不通过用户授权直接获取unionid,所以应该要借助这个机制,帮助用户实现无需任何操作即可直接登录的效果。
  核心机制七,交互层面处理用户拒绝授权妥善处理用户拒绝授权,所以拿不到unionid的情况。
  核心机制八,用户标识变更后的广播机制所有涉及userid之间替换的行为,必须广播至所有业务线,不论是虚拟的userid被真实登录的userid替换,还是虚拟的userid之间的替换。
  其中核心机制一、二、三、六、七都是在上文讨论过的,核心机制四在本小节的开头部分已经讨论过,我们就来说一下核心机制五和核心机制八。
  我们不妨来对比一下涉及游客生单和不涉及游客生单对于核心机制五的设计上的不同要求
  【涉及游客生单】
  从小程序内获得的unionid,在微信网页内获得的unionid和App基于账户绑定获得的unionid是一致的,所以三者其一如果在数据库已经建立了unionid和userid的关联数据,剩余两方应该可以借助数据库内的数据自动建立联系而不需要用户在做任何类似于手机号验证码登录的身份识别操作。这个关联逻辑需要对游客身份生成的虚拟userid也同样生效。
  【不涉及游客生单】
  从小程序内获得的unionid和在微信网页内获得的unionid是一致的,所以二者其一如果在数据库已经建立了unionid和userid的关联数据,另一方应该可以借助数据库内的数据自动建立联系而不需要用户在做任何类似于手机号验证码登录的身份识别操作。
  排除增加了App这个运行环境之外,最大的不同点在于这个关联逻辑需要对游客身份生成的虚拟userid也同样生效。这句话。
  为什么需要这么做呢?主要是为了满足如下场景:
  用户在小程序同意了用户信息授权,系统获得了她的openid和unionid,但是她紧接着以游客身份生单,并没有登录。
  这个时候用户又在微信内网页做了同样的事情,这个时候系统如果不对她作为游客身份的userid做同步,那么她在两个环境的cookie是不一样的,生成的虚拟userid自然就不同,但是系统基于unionid应该是能对用户在不同的地方的数据做整合同步的。
  可能有的人会说,竭尽全力帮助用户同步数据会不会让用户觉得毛骨悚然,我觉得这是无稽之谈,我做过很多用户访谈,很多人甚至分不清小程序和微信内网页之间的区别,在他们看来,数据就应该是同步的,丢数据才会让他们毛骨悚然。
  基于上面的讨论,我们再次将流程图做修正,就得到了如下的流程图:
  与上方的流程图相比,唯一的区别在于判断userid是否为空的逻辑变成了userid是不是都是虚拟,因为在游客生单的机制下,即使用户不登录,也可以获得一个虚拟userid。
  在做userid的关联补充的时候,如果系统能够识别用户身份(基于获取到的unionid),那么即使当前userid是虚拟的,数据库中早先用户数据的userid也是虚拟的,也需要保持useridunionid一一对应的关系,将现在这个虚拟的userid替换成数据库中更早的那一个,这样用户先前的数据就可以在这个环境被读取出来,具体的应用场景在上方已经描述。但是假如其中有一个userid是真实的,那么它应该获得最高的优先级。
  后记
  至此,关于整个微信账户体系如何建设的论述就告一段落了。其实想要打造完整的用户体系还有很多可以做的事情,比如除了微信,是否能支持QQ和微博的登录,比如第三方社交账户是否支持解绑(一般大公司的用户中心都做了这个功能),都是我们需要考虑的问题,但是我觉得在前期只需要做好微信就够了。
  如果将微博和QQ的数据加入进来,那么整体数据结构就会呈现如下的分布:
  而整体的产品结构会呈现如下样式:
  其实在正式开始写这篇文章之后,才有时间沉下心来再次对逻辑抽象,想出了上文中的流程图。
  在那之前我给开发看也好,自己检查也好,思考的逻辑都是一个类似于二叉树的逻辑。但是随着业务复杂度的提高,二叉树的逻辑很明显只能用来做覆盖性测试,不适合用来做开发,这算是在这件事情过程中踩得一个不大不小的坑吧。
  我觉得用户体系这个东西发展了这么多年,看上去很简单,但是其实里面深究起来学问也不少,但是总的来说在实际工作的时候,还是要牢牢把握住底层的核心思想,好的用户体系主要就是做两个事情,身份识别和限权。所有的工作都应该围绕身份之别和限权这两个底层需要去做的,其实我们所做的一切,万变不离其宗,就是如何让用户把身份识别的成本降到最低,如何让系统限权做的最准确。
  不妨回想一下,以前的用户体系还会区分注册和登录,现在基本上就是手机短信验证码登录,没注册默认注册,这个变化其实就是上面所提到的核心思想的一个实践方案,而且经过业界各个大厂的实践,基本上可以认为是一种最佳实践方案了。
  从个人角度来看,微信这个openid和unionid的机制非常的蛋疼,微信自己也作出过不少次改进,但是我觉得这仍然是一件非常操蛋而且麻烦的事情。从微信官方的角度来看,他们或许还是出于保护用户隐私不被滥用的角度在做这件事情,而作为开发者也只有适应的份,毕竟这个机制已经在这边了,没啥好说的。
  上面文章内的很多想法,大部分我都实践过,效果是符合预期的,但是由于客观条件的限制,有一些想法并没有在生产环境得到过验证,并不能保证100正确,况且不同的业务场景,对于同一件事情会衍生出不同的实践方案,比如本文会强调尽量做到【useridunionid】一一对应,在实践中有一些公司是允许一个userid对应多个unionid的,其实仔细想一下,好像也没什么大毛病。
  感谢如下的小伙伴给本文提供的支持
  十一贝科技前端工程师周航
  某待业的前端工程师权金铎
  十一贝科技资深java工程师李锐
  厨芯科技产品经理邵琨容
  虎嗅编辑小田一成
  文章内的流程图都是使用的OmniGraffle和Xmind绘制而成,如果有需要源文件或者有一些别的想法,欢迎添加我的微信做进一步交流。
投诉 评论 转载

Axure教程:苹果手机拨号原型对于我们每天熟悉得不能再熟悉的拨号键盘,你有没有想过它背后的交互设计理念是什么,它是如何通过Axure实现的呢?在本文中,笔者将告诉你这些问题的答案。对于我们再熟悉不过的……搞定微信生态内的账户体系,看这篇文章就够了笔者从私域流量出发,论述了不同的业务和场景下如何处理微信私域相关的用户数据,并分享了自己的操作建议。最近私域流量的概念非常火,所谓私域流量,就是你可以自由反复利用,无需付……Axure8:如何制作应用同时添加和删除交互效果如何制作添加删除应用时同时操作的效果,本文简单的介绍了一下,一起来看看APP首屏九宫格中如果“快捷应用”入口超过一定数量时,一般会采用更多页来进行筛选编辑,那如何制作添加……Axure教程:如何制作可伸缩的全局导航?可伸缩的全局导航可以帮助用户寻找到感兴趣的类目,鼠标在一级分类上悬停,一级分类下的二级和三级分类就会显示出来,结束悬停时,二级和三级分类就会收缩起来。话不多说,立马开始分……Axure8。0:仿“人人都是PM”首页导航本文是关于在Axure8。0中,如何去仿制“人人都是PM”首页导航,一起来看看原效果图:我的电脑屏幕分辩率是1366768,所以在这里取可视区为1345,故拖入矩形……技巧分享:Axure后台组件制作的全过程大家好,前一段时间我刚刚分享了一篇《打造高品质Axure组件库就是这么简单》,意在分享给大家一个完整的打造axure组件的思维路径。本文着重于整体制作的技巧思路分享,希望大家通……AxureRP9教程:模拟登录注册本篇文章将会教大家利用AxureRP9,制作显示密码和隐藏密码的交互效果,enjoy前言本期案例给大家展示的交互内容包括:60s倒计时动态面板的简单切换……Axure教程:快速搭建有滚动交互效果的网页框架(附源文件下绘制网页原型说来简单,技术上与系统、产品的原型相比大同小异。但我们会发现,将几个内容区域画好后罗列在一起,预览时的效果总觉得与真实的网站有很大差距。而问题的关键,便在于是否能够……Axure教程:中继器基础应用数据展示、新增、删除中继器Axure中复杂的元件,没有之一。中继器是Axure中最强大的元件,通常用于页面效果展示时使用。但对于新手小白来说,这个元件的使用不是那么的友好,学习成本较高在本文中,将……Axure教程:如何制作有趣的小红书促销小游戏?如何利用Axure来制作有趣的小红书促销小游戏?一起来文中看看温馨提示注:本教程适合有Axure基础的人观看首先我们先看看制作的效果:操作说明:长按圆脸,脸会……发送验证码,倒计时重新发送的案例教程“发送验证码,倒计时重新发送”,这个功能在产品中非常常见,本篇文章笔者将会以两种方法来展示如何实现这个功能,enjoy一、案例目标今天这个教程中,我会用2种方法实现……Axure教程:简单的提高效率神器母版在制作后台原型时,你是否还在使用“Ctrlc”“Ctrlv”的方式来重复使用模板呢?你是否因为需求变动导致需要对所有页面的菜单都进行“流水线式”的修改呢?这些个方法不仅花费时间……
旅游APP竞品分析报告:携程vs去哪儿旅行vs飞猪出境游小肚皮App产品分析:00后的社交养成平台产品分析报告:共享衣橱行业,缘何衣二三成为独角兽?Soul分析报告:弱社交如何成为强依恋透过乐信“分期乐”产品,看消费金融行业2019年抖音数据报告的分析探究西梅产品体验报告:少壮不努力,老大学英语产品分析:微信读书,当阅读成为一种社交方式DaDa英语VSVIPKID:进入2。0模式,寻找更多可能对比分析:京东VS淘宝,从购物车形态分析营销策略微信网页版,为什么要二维码登录?产品分析哔哩哔哩,年轻人的文化社区

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找作文动态热点娱乐育儿情感教程科技体育养生教案探索美文旅游财经日志励志范文论文时尚保健游戏护肤业界