OAuthApi.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #region Apache License Version 2.0
  2. /*----------------------------------------------------------------
  3. Copyright 2019 Jeffrey Su & Suzhou Senparc Network Technology Co.,Ltd.
  4. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
  5. except in compliance with the License. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software distributed under the
  8. License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  9. either express or implied. See the License for the specific language governing permissions
  10. and limitations under the License.
  11. Detail: https://github.com/JeffreySu/WeiXinMPSDK/blob/master/license.md
  12. ----------------------------------------------------------------*/
  13. #endregion Apache License Version 2.0
  14. /*----------------------------------------------------------------
  15. Copyright(C) 2017 Senparc
  16. 文件名:OAuthAPI.cs
  17. 文件功能描述:OAuth
  18. 创建标识:Senparc - 20150211
  19. 修改标识:Senparc - 20150303
  20. 修改描述:整理接口
  21. 修改标识:Senparc - 20160719
  22. 修改描述:增加其接口的异步方法
  23. ----------------------------------------------------------------*/
  24. /*
  25. 官方文档:http://mp.weixin.qq.com/wiki/index.php?title=%E7%BD%91%E9%A1%B5%E6%8E%88%E6%9D%83%E8%8E%B7%E5%8F%96%E7%94%A8%E6%88%B7%E5%9F%BA%E6%9C%AC%E4%BF%A1%E6%81%AF#.E7.AC.AC.E4.B8.80.E6.AD.A5.EF.BC.9A.E7.94.A8.E6.88.B7.E5.90.8C.E6.84.8F.E6.8E.88.E6.9D.83.EF.BC.8C.E8.8E.B7.E5.8F.96code
  26. */
  27. using System.Threading.Tasks;
  28. using Senparc.CO2NET.Extensions;
  29. using Senparc.NeuChar;
  30. using Senparc.Weixin.CommonAPIs;
  31. using Senparc.Weixin.Entities;
  32. using Senparc.Weixin.HttpUtility;
  33. using Senparc.Weixin.MP.AdvancedAPIs.OAuth;
  34. using Senparc.Weixin.MP.CommonAPIs;
  35. namespace Senparc.Weixin.MP.AdvancedAPIs
  36. {
  37. public static class OAuthApi
  38. {
  39. #region 同步方法
  40. /*此接口不提供异步方法*/
  41. /// <summary>
  42. /// 获取验证地址
  43. /// </summary>
  44. /// <param name="appId">公众号的唯一标识</param>
  45. /// <param name="redirectUrl">授权后重定向的回调链接地址,请使用urlencode对链接进行处理</param>
  46. /// <param name="state">重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节</param>
  47. /// <param name="scope">应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)</param>
  48. /// <param name="responseType">返回类型,请填写code(或保留默认)</param>
  49. /// <param name="addConnectRedirect">加上后可以解决40029-invalid code的问题(测试中)</param>
  50. /// <returns></returns>
  51. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "OAuthApi.GetAuthorizeUrl", true)]
  52. public static string GetAuthorizeUrl(string appId, string redirectUrl, string state, OAuthScope scope, string responseType = "code", bool addConnectRedirect = true)
  53. {
  54. var url =
  55. string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type={2}&scope={3}&state={4}{5}#wechat_redirect",
  56. appId.AsUrlData(), redirectUrl.AsUrlData(), responseType.AsUrlData(), scope.ToString("g").AsUrlData(), state.AsUrlData(),
  57. addConnectRedirect ? "&connect_redirect=1" : "");
  58. /* 这一步发送之后,客户会得到授权页面,无论同意或拒绝,都会返回redirectUrl页面。
  59. * 如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。这里的code用于换取access_token(和通用接口的access_token不通用)
  60. * 若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=STATE
  61. */
  62. return url;
  63. }
  64. /// <summary>
  65. /// 获取AccessToken(OAuth专用)
  66. /// </summary>
  67. /// <param name="appId">公众号的唯一标识</param>
  68. /// <param name="secret">公众号的appsecret</param>
  69. /// <param name="code">code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。</param>
  70. /// <param name="grantType">填写为authorization_code(请保持默认参数)</param>
  71. /// <returns></returns>
  72. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "OAuthApi.GetAccessToken", true)]
  73. public static OAuthAccessTokenResult GetAccessToken(string appId, string secret, string code, string grantType = "authorization_code")
  74. {
  75. var url =
  76. string.Format(Config.ApiMpHost + "/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type={3}",
  77. appId.AsUrlData(), secret.AsUrlData(), code.AsUrlData(), grantType.AsUrlData());
  78. return CommonJsonSend.Send<OAuthAccessTokenResult>(null, url, null, CommonJsonSendType.GET);
  79. }
  80. /// <summary>
  81. /// 刷新(OAuth专用)access_token(如果需要)
  82. /// </summary>
  83. /// <param name="appId">公众号的唯一标识</param>
  84. /// <param name="refreshToken">填写通过access_token获取到的refresh_token参数</param>
  85. /// <param name="grantType">填写refresh_token</param>
  86. /// <returns></returns>
  87. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "OAuthApi.RefreshToken", true)]
  88. public static RefreshTokenResult RefreshToken(string appId, string refreshToken, string grantType = "refresh_token")
  89. {
  90. var url =
  91. string.Format(Config.ApiMpHost + "/sns/oauth2/refresh_token?appid={0}&grant_type={1}&refresh_token={2}",
  92. appId.AsUrlData(), grantType.AsUrlData(), refreshToken.AsUrlData());
  93. return CommonJsonSend.Send<RefreshTokenResult>(null, url, null, CommonJsonSendType.GET);
  94. }
  95. /// <summary>
  96. /// 获取用户基本信息
  97. /// </summary>
  98. /// <param name="oauthAccessToken">调用接口凭证(OAuth专用)</param>
  99. /// <param name="openId">普通用户的标识,对当前公众号唯一</param>
  100. /// <param name="lang">返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语</param>
  101. /// <returns></returns>
  102. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "OAuthApi.GetUserInfo", true)]
  103. public static OAuthUserInfo GetUserInfo(string oauthAccessToken, string openId, Language lang = Language.zh_CN)
  104. {
  105. var url = string.Format(Config.ApiMpHost + "/sns/userinfo?access_token={0}&openid={1}&lang={2}", oauthAccessToken.AsUrlData(), openId.AsUrlData(), lang.ToString("g").AsUrlData());
  106. return CommonJsonSend.Send<OAuthUserInfo>(null, url, null, CommonJsonSendType.GET);
  107. }
  108. /// <summary>
  109. /// 检验授权凭证(access_token)是否有效(OAuth专用)
  110. /// </summary>
  111. /// <param name="oauthAccessToken">调用接口凭证(OAuth专用)</param>
  112. /// <param name="openId">用户的唯一标识</param>
  113. /// <returns></returns>
  114. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "OAuthApi.Auth", true)]
  115. public static WxJsonResult Auth(string oauthAccessToken, string openId)
  116. {
  117. var url = string.Format(Config.ApiMpHost + "/sns/auth?access_token={0}&openid={1}", oauthAccessToken.AsUrlData(), openId.AsUrlData());
  118. return CommonJsonSend.Send<WxJsonResult>(null, url, null, CommonJsonSendType.GET);
  119. }
  120. #endregion
  121. #if !NET35 && !NET40
  122. #region 异步方法
  123. /// <summary>
  124. /// 【异步方法】获取AccessToken(OAuth专用)
  125. /// </summary>
  126. /// <param name="appId"></param>
  127. /// <param name="secret"></param>
  128. /// <param name="code">code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。</param>
  129. /// <param name="grantType"></param>
  130. /// <returns></returns>
  131. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "OAuthApi.GetAccessTokenAsync", true)]
  132. public static async Task<OAuthAccessTokenResult> GetAccessTokenAsync(string appId, string secret, string code, string grantType = "authorization_code")
  133. {
  134. var url =
  135. string.Format(Config.ApiMpHost + "/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type={3}",
  136. appId.AsUrlData(), secret.AsUrlData(), code.AsUrlData(), grantType.AsUrlData());
  137. return await Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync<OAuthAccessTokenResult>(null, url, null, CommonJsonSendType.GET);
  138. }
  139. /// <summary>
  140. ///【异步方法】刷新(OAuth专用)access_token(如果需要)
  141. /// </summary>
  142. /// <param name="appId"></param>
  143. /// <param name="refreshToken">填写通过access_token获取到的refresh_token参数</param>
  144. /// <param name="grantType"></param>
  145. /// <returns></returns>
  146. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "OAuthApi.RefreshTokenAsync", true)]
  147. public static async Task<OAuthAccessTokenResult> RefreshTokenAsync(string appId, string refreshToken, string grantType = "refresh_token")
  148. {
  149. var url =
  150. string.Format(Config.ApiMpHost + "/sns/oauth2/refresh_token?appid={0}&grant_type={1}&refresh_token={2}",
  151. appId.AsUrlData(), grantType.AsUrlData(), refreshToken.AsUrlData());
  152. return await Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync<OAuthAccessTokenResult>(null, url, null, CommonJsonSendType.GET);
  153. }
  154. /// <summary>
  155. ///【异步方法】 获取用户基本信息
  156. /// </summary>
  157. /// <param name="oauthAccessToken">调用接口凭证(OAuth专用)</param>
  158. /// <param name="openId">普通用户的标识,对当前公众号唯一</param>
  159. /// <param name="lang">返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语</param>
  160. /// <returns></returns>
  161. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "OAuthApi.GetUserInfoAsync", true)]
  162. public static async Task<OAuthUserInfo> GetUserInfoAsync(string oauthAccessToken, string openId, Language lang = Language.zh_CN)
  163. {
  164. var url = string.Format(Config.ApiMpHost + "/sns/userinfo?access_token={0}&openid={1}&lang={2}", oauthAccessToken.AsUrlData(), openId.AsUrlData(), lang.ToString("g").AsUrlData());
  165. return await Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync<OAuthUserInfo>(null, url, null, CommonJsonSendType.GET);
  166. }
  167. /// <summary>
  168. /// 【异步方法】检验授权凭证(access_token)是否有效(OAuth专用)
  169. /// </summary>
  170. /// <param name="oauthAccessToken">调用接口凭证(OAuth专用)</param>
  171. /// <param name="openId">用户的唯一标识</param>
  172. /// <returns></returns>
  173. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "OAuthApi.AuthAsync", true)]
  174. public static async Task<WxJsonResult> AuthAsync(string oauthAccessToken, string openId)
  175. {
  176. var url = string.Format(Config.ApiMpHost + "/sns/auth?access_token={0}&openid={1}", oauthAccessToken.AsUrlData(), openId.AsUrlData());
  177. return await Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync<WxJsonResult>(null, url, null, CommonJsonSendType.GET);
  178. }
  179. #endregion
  180. #endif
  181. }
  182. }