背景

随着公司微信相关业务场景的不断拓展,从最初的一个微信移动应用、然后发展成微信公众号应用、然后又有了微信小程序应用。但是随着应用的拓展,如何保证相同用户的微信用户在不同应用中登录的同一个账号呢?今天的主题就来了.NET微信网页开发之通过UnionID机制解决多应用用户帐号统一问题。

UnionID 机制

如果开发者拥有多个移动应用、网站应用、和公众账号(包括小程序),可通过 UnionID 来区分用户的唯一性,因为只要是同一个微信开放平台账号下的移动应用、网站应用和公众账号(包括小程序),用户的 UnionID 是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,UnionID是相同的。

获取用户基本信息(UnionID机制)

在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。公众号可通过本接口来根据OpenID获取用户基本信息,包括语言和关注时间。

请注意,如果开发者有在多个公众号,或在公众号、移动应用之间统一用户账号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。

微信开放平台配置

登录地址:https://open.weixin.qq.com/

微信公众号微信登录配置

在基本配置中获取微信公众号的appid和appsecrect(一定是要自己公众号的),白名单是你在本地调试的微信项目的时候需要添加的你本地的ip地址,不然获取不到你想要的accsee_token。

配置服务器地址(url):这里是你的项目与微信服务器通讯的地方,一定不能填错,Token是你项目中的,将其复制到这里即可,消息加密解密密钥是微信端随机生成的。

在微信公众号设置设置对应业务域名,js接口安全域名,以及网页授权域名:

微信网页公众号获取用户UnionID(用户统一标识)

注意:用户统一标识(针对一个微信开放平台账号下的应用,同一用户的 unionid 是唯一的),只有当scope为"snsapi_userinfo"时返回

用户同意授权获取code

在确保微信公众账号拥有授权作用域(scope参数)的权限的前提下(已认证服务号,默认拥有scope参数中的snsapi_base和snsapi_userinfo 权限),引导关注者打开如下页面:

若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。跳转回调redirect_uri,应当使用https链接来确保授权code的安全性,并且是在微信公众号后台配置的网页授权域名的访问地址。

  • https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

请求参数:

通过code获取用户UnionID(用户统一标识)

  • 获取code后,请求以下链接获取access_token:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

请求参数:

返回参数:

请求示例代码:

    public class WeChatLogin : Controller
    {

        /// <summary>
        /// 获取用户UnionID(用户统一标识)
        /// </summary>
        /// <param name="state">自定义参数</param>
        /// <param name="code">通过用户授权后得到的code</param>
        /// <returns></returns>
        public async Task<Response> GetWeChatUnionID(string state, string code)
        {
            string appId = "YourAppId";
            string appSecret = "YourAppSecret";
            string requestUrl = $"https://api.weixin.qq.com/sns/oauth2/access_token?appid={appId}&secret={appSecret}&code={code}&grant_type=authorization_code";

            using (var httpClient = new HttpClient())
            {
                var httpRequest = new HttpRequestMessage(HttpMethod.Get, requestUrl);
                using (var response = await httpClient.SendAsync(httpRequest))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        var responseString = await response.Content.ReadAsStringAsync();
                        var responseData = JsonConvert.DeserializeObject<WeChatTokenResponse>(responseString);

                        return new Response
                        {
                            Code = 1,
                            Message = responseData.UnionId
                        };
                    }
                    else
                    {
                        var errorResponseString = await response.Content.ReadAsStringAsync();
                        var errorData = JsonConvert.DeserializeObject<ErrorResponse>(errorResponseString);

                        return new Response
                        {
                            Code = 0,
                            Message = $"Failed to get access token: {errorData.ErrMsg}"
                        };
                    }
                }
            }
        }
    }

    public class WeChatTokenResponse
    {
        [JsonProperty("access_token")]
        public string AccessToken { get; set; }

        [JsonProperty("expires_in")]
        public int ExpiresIn { get; set; }

        [JsonProperty("refresh_token")]
        public string RefreshToken { get; set; }

        [JsonProperty("openid")]
        public string OpenId { get; set; }

        [JsonProperty("scope")]
        public string Scope { get; set; }

        [JsonProperty("is_snapshotuser")]
        public int IsSnapshotUser { get; set; }

        [JsonProperty("unionid")]
        public string UnionId { get; set; }
    }

    public class ErrorResponse
    {
        [JsonProperty("errcode")]
        public int ErrCode { get; set; }

        [JsonProperty("errmsg")]
        public string ErrMsg { get; set; }
    }

.NET微信网页开发相关文章教程

https://github.com/YSGStudyHards/DotNetGuide

DotNetGuide技术社区交流群

  • DotNetGuide技术社区是一个面向.NET开发者的开源技术社区,旨在为开发者们提供全面的C#/.NET/.NET Core相关学习资料、技术分享和咨询、项目推荐、招聘资讯和解决问题的平台。
  • 在这个社区中,开发者们可以分享自己的技术文章、项目经验、遇到的疑难技术问题以及解决方案,并且还有机会结识志同道合的开发者。
  • 我们致力于构建一个积极向上、和谐友善的.NET技术交流平台,为广大.NET开发者带来更多的价值和成长机会。

欢迎加入DotNetGuide技术社区微信交流群

参考文章

https://developers.weixin.qq.com/doc/offiaccount/User_Management/Get_users_basic_information_UnionID.html

.NET微信网页开发之通过UnionID机制解决多应用用户帐号统一问题的更多相关文章

  1. 10天学会phpWeChat——第十天:phpWeChat的会员注册、登录以及微信网页开发

    通过前面的系列教程,我们系统的讲解了phpWeChat从视图端.控制器端到模型端的操作流程:熟悉了phpWeChat的目录结构:掌握了视图端模板如何创建一个丰富的表单和模型端如何操作数据库.这一切都是 ...

  2. 微信公众平台可通过UnionID机制在多公众号间帐号互通

    微信公众平台越来越注重开发者的反馈信息了,这不,微信开放平台提供了UnionID机制,通过获取用户基本信息接口,开发者可通过OpenID来获取用户基本信息,而如果开发者拥有多个公众号,可使用以下办法通 ...

  3. 微信网页开发调用微信jssdk接口遇到的坑以及最终解决方法 (持续更新)

    1.微信网页开发调用jssdk时报permission denied 大致是两个原因 (1)首先注册时未将你所调用的接口名字添加至jsApiList (2)第二个就是你的这个公众号没有权限使用这个ap ...

  4. 微信开发+百度AI学习:微信网页开发环境搭建

    参考微信官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 两步即可获取微信网页开发能力 STEP1: ...

  5. 微信网页开发之获取用户unionID的两种方法--基于微信的多点登录用户识别

    假设网站A有以下功能需求:1,pc端微信扫码登录:2,微信浏览器中的静默登录功能需求,这两种需求就需要用到用户的unionID,这样才能在多个登录点(终端)识别用户.那么这两种需求下用户的unionI ...

  6. 微信网页开发之创建Controller(三)

    首先,我们需要在App区域下添加一个控制器,这里我们就以AppDemoController为例.如下图所示: 注意:你也可以自己创建其他区域,只是这里推荐使用App区域. 创建好之后,请添加自己的Ac ...

  7. .Net微信网页开发之使用微信JS-SDK自定义微信分享内容

    第一步.微信JS-SDK的使用步骤,配置信息的生成获取讲解: 关于JS-SDK的使用步骤和timestamp(时间戳),nonceStr(随机串),signature(签名),access_token ...

  8. .Net微信网页开发之使用微信JS-SDK调用微信扫一扫功能

    前言: 之前有个项目需要调用微信扫描二维码的功能,通过调用微信扫码二维码功能,然后去获取到系统中生成的二维码信息.正好微信JS-SDK提供了调用微信扫一扫的功能接口,下面让我们来看看是如何实现的吧. ...

  9. Net微信网页开发之使用微信JS-SDK获取当前地理位置

    前言: 前段时间有一个关于通过获取用户当前经纬度坐标,计算出该用户距离某指定地点之间的距离.因为做这个项目需要能够获取到比较精确的经纬度坐标,刚开始使用的是百度地图结果发现百度地图地位不太准确(有时候 ...

  10. PayPal 开发详解(一):注册PayPal帐号

    1.注册paypal帐号 https://www.paypal.com 2.使用刚才注册的paypal帐号登录3.进入开发者中心 4.登录开发者中心 5.登录 查看我们paypal Sandbox测试 ...

随机推荐

  1. Inno SetUp安装包:如何在程序安装时卸载驱动程序

    pnputil命令行方式卸载 如果您想通过命令行卸载.INF文件的驱动程序,您需要使用PnPUtil命令.以下是一个示例: pnputil /delete-driver oem0.inf /unins ...

  2. 云上的甜蜜早安:腾讯云云函数助力PHP打造女友专属每日推送

    用腾讯云的云函数做一个微信公众号早安,每天定时发送早安给你的女朋友! 1.首先我们登录腾讯云,在搜索栏搜索云函数,或直接用这个链接进入curl.qcloud.com/Td0IkpmD 2.进入云函数, ...

  3. 在.NET 8 RC1 版本中 MAUI、ASP.NET Core 和 EF8 的新特性

    从年初2 月份发布第一个预览版,经历7个预览版后,Microsoft 西雅图时间9月13日发布了 .NET 8  RC 1: https://devblogs.microsoft.com/dotnet ...

  4. Ds100p -「数据结构百题」总集

    (来自 2021 的 ps:这个页面是几百年前写的,很丑,caution!) 前言 \(\qquad \qquad \qquad\)ljs搞了一个dp100题,然后lyc告诉我我们搞一个数据结构100 ...

  5. TiDB的简单介绍以及进行资源限制的方式与方法

    TiDB的简单介绍以及进行资源限制的方式与方法 TiDB的简介 TiDB是一个分布式数据库, 简介为: TiDB 是一个开源的分布式关系型数据库,它兼具了分布式数据库的水平扩展性和传统关系型数据库的 ...

  6. mysql8安装踩坑记

    背景:已安装mysql5.7版本 问题一:默认的3306端口被占用 进入mysql5.7的my.ini文件,更改port为3307或者其他未被占用的端口 问题二:Install/Remove of t ...

  7. 使用 gopkg.in/yaml.v3 解析 YAML 数据

    YAML(YAML Ain't Markup Language)是一种人类可读的数据序列化格式,常用于配置文件和数据交换.在 Go 语言中,你可以使用 gopkg.in/yaml.v3 包来解析和生成 ...

  8. 单元测验4:人格知识大比武2mooc

    单元测验4:人格知识大比武2 返回 本次得分为:10.00/10.00, 本次测试的提交时间为:2020-09-06, 如果你认为本次测试成绩不理想,你可以选择 再做一次 . 1 单选(2分) 关于M ...

  9. [ABC212E] Safety Journey 题解

    Safety Journey 题目大意 给定一张缺少了 \(m\) 条边的 \(n\) 个点的完全图和一个正整数 \(k\),你需要求出满足以下条件的序列 \(A\) 的数量: \(A\) 的长度为 ...

  10. 深入理解 Python 虚拟机:进程、线程和协程

    深入理解 Python 虚拟机:进程.线程和协程 在本篇文章当中深入分析在 Python 当中 进程.线程和协程的区别,这三个概念会让人非常迷惑.如果没有深入了解这三者的实现原理,只是看一些文字说明, ...