微信第三方登录
1 string returnUrl = string.Empty; 2 string appId = ConfigurationManager.AppSettings["wx_AppKey"]; 3 string appSecret = ConfigurationManager.AppSettings["wx_AppSecret"]; 4 5 var weixinOAuth = new WeiXinOAuth(); 6 string code = Request.QueryString["code"]; 7 string state = Request.QueryString["state"]; 8 9 if (string.IsNullOrEmpty(code) || code == "authdeny") 10 { 11 if (string.IsNullOrEmpty(code)) 12 { 13 //发起授权(第一次微信握手) 14 string authUrl = weixinOAuth.GetWeiXinCode(appId, appSecret, Server.UrlEncode(Request.Url.ToString()), true); 15 Response.Redirect(authUrl, true); 16 } 17 else 18 { 19 // 用户取消授权 20 ViewData["StatusMessageData"] = new StatusMessageData(StatusMessageType.Error, "授权失败!"); 21 } 22 } 23 else 24 { 25 //获取微信的Access_Token(第二次微信握手) 26 var modelResult = weixinOAuth.GetWeiXinAccessToken(appId, appSecret, code); 27 //获取微信的用户信息(第三次微信握手) 28 var userInfo = weixinOAuth.GetWeiXinUserInfo(modelResult.SuccessResult.access_token, modelResult.SuccessResult.openid); 29 //用户信息(判断是否已经获取到用户的微信用户信息) 30 if (userInfo.Result && userInfo.UserInfo.openid != "") 31 { 32 //根据OpenId判断数据库是否存在,如果存在,直接登录即可 33 if (CurrentUser != null) 34 { 35 if (AccountBindings.GetUser(2, userInfo.UserInfo.openid) == null) 36 { 37 AccountBinding account = new AccountBinding(); 38 account.AccountType = 2; 39 account.Identification = userInfo.UserInfo.openid; 40 account.UserID = CurrentUser.UserID; 41 account.OauthToken = modelResult.SuccessResult.access_token; 42 account.OauthTokenSecret = appSecret; 43 AccountBindings.CreateAccountBinding(account); 44 45 ViewData["StatusMessageData"] = new StatusMessageData(StatusMessageType.Success, "绑定成功"); 46 } 47 else 48 { 49 ViewData["StatusMessageData"] = new StatusMessageData(StatusMessageType.Hint, "此账号已在网站中绑定过,不可再绑定其他网站账号"); 50 } 51 } 52 else 53 { 54 User systemUser = AccountBindings.GetUser(2, userInfo.UserInfo.openid); 55 if (systemUser != null) 56 { 57 FormsAuthentication.SetAuthCookie(systemUser.UserName, true); 58 returnUrl = SiteUrls.Instance().UserDomainHome(systemUser); 59 ViewData["StatusMessageData"] = new StatusMessageData(StatusMessageType.Success, "登录成功"); 60 } 61 else 62 { 63 ViewData["StatusMessageData"] = new StatusMessageData(StatusMessageType.Success, string.Empty); 64 ViewData["UserName"] = WebUtils.UrlEncode(userInfo.UserInfo.nickname); 65 string nickName = WebUtils.UrlEncode(userInfo.UserInfo.nickname); 66 string figureurl = userInfo.UserInfo.headimgurl; 67 ViewData["FirstLogin"] = true; 68 returnUrl = SPBUrlHelper.Action("ThirdRegister", "ChannelUser", new RouteValueDictionary { { "accountType", 2 }, { "openID", userInfo.UserInfo.openid }, { "OauthToken", modelResult.SuccessResult.access_token }, { "OauthTokenSecret", appSecret }, { "nickName", nickName }, { "figureurl", figureurl } }); 69 } 70 } 71 } 72 else 73 { 74 ViewData["StatusMessageData"] = new StatusMessageData(StatusMessageType.Error, "参数错误,授权失败!"); 75 } 76 } 77 78 ViewData["returnUrl"] = returnUrl; 79 return View("Pages/User/LoginCallback.aspx");
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Web; 6 using System.Net; 7 using System.IO; 8 using System.Collections.Specialized; 9 using System.Text.RegularExpressions; 10 using System.Globalization; 11 using System.Web.Security; 12 using System.Web.UI; 13 using System.Web.UI.WebControls; 14 using System.Web.UI.WebControls.WebParts; 15 using System.Web.UI.HtmlControls; 16 using SpaceBuilder.Common; 17 using Jayrock.Json.Conversion; 18 using System.Configuration; 19 20 21 public class WeiXinOAuth 22 { 23 public enum Method { GET, POST, PUT, DELETE }; 24 /// <summary> 25 /// 获取微信Code 26 /// </summary> 27 /// <param name="appId">微信AppId</param> 28 /// <param name="appSecret">微信AppSecret</param> 29 /// <param name="redirectUrl">返回的登录地址,要进行Server.Un编码</param> 30 /// <param name="isWap">true=微信内部登录 false=pc网页登录</param> 31 public string GetWeiXinCode(string appId, string appSecret, string redirectUrl, string state, bool isWap) 32 { 33 var r = new Random(); 34 //微信登录授权 35 //string url = "https://open.weixin.qq.com/connect/qrconnect?appid=" + appId + "&redirect_uri=" + redirectUrl +"&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect"; 36 //微信OpenId授权 37 //string url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + redirectUrl +"&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect"; 38 //微信用户信息授权 39 var url = ""; 40 if (isWap) 41 { 42 url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + 43 redirectUrl + "&response_type=code&scope=snsapi_userinfo&state=" + state + "#wechat_redirect"; 44 } 45 else 46 { 47 url = "https://open.weixin.qq.com/connect/qrconnect?appid=" + appId + "&redirect_uri=" + redirectUrl + 48 "&response_type=code&scope=snsapi_login&state=" + state + "#wechat_redirect"; 49 } 50 return url; 51 } 52 /// <summary> 53 /// 通过code获取access_token 54 /// </summary> 55 /// <param name="appId"></param> 56 /// <param name="appSecret"></param> 57 /// <param name="code"></param> 58 /// <returns></returns> 59 public WeiXinAccessTokenResult GetWeiXinAccessToken(string appId, string appSecret, string code) 60 { 61 string url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appSecret + 62 "&code=" + code + "&grant_type=authorization_code"; 63 string jsonStr = _WebRequest(Method.GET, url, ""); 64 var result = new WeiXinAccessTokenResult(); 65 if (jsonStr.Contains("errcode")) 66 { 67 var errorResult = (WeiXinHelper.WeiXinErrorMsg)JsonConvert.Import(typeof(WeiXinHelper.WeiXinErrorMsg), jsonStr); 68 result.ErrorResult = errorResult; 69 result.Result = false; 70 } 71 else 72 { 73 var model = (WeiXinAccessTokenModel)JsonConvert.Import(typeof(WeiXinAccessTokenModel), jsonStr); 74 result.SuccessResult = model; 75 result.Result = true; 76 } 77 return result; 78 } 79 /// <summary> 80 /// 拉取用户信息 81 /// </summary> 82 /// <param name="accessToken"></param> 83 /// <param name="openId"></param> 84 /// <returns></returns> 85 public WeiXinHelper.WeiXinUserInfoResult GetWeiXinUserInfo(string accessToken, string openId) 86 { 87 string url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openId + "⟨=zh_CN"; 88 string jsonStr = _WebRequest(Method.GET ,url,""); 89 var result = new WeiXinHelper.WeiXinUserInfoResult(); 90 if (jsonStr.Contains("errcode")) 91 { 92 var errorResult = (WeiXinHelper.WeiXinErrorMsg)JsonConvert.Import(typeof(WeiXinHelper.WeiXinErrorMsg), jsonStr); 93 result.ErrorMsg = errorResult; 94 result.Result = false; 95 } 96 else 97 { 98 var userInfo = (WeiXinHelper.WeiXinUserInfo)JsonConvert.Import(typeof(WeiXinHelper.WeiXinUserInfo), jsonStr); 99 result.UserInfo = userInfo; 100 result.Result = true; 101 } 102 return result; 103 } 104 105 106 private string _WebRequest(Method method, string url, string postData) 107 { 108 HttpWebRequest webRequest = null; 109 StreamWriter requestWriter = null; 110 string responseData = ""; 111 112 webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest; 113 webRequest.Method = method.ToString(); 114 webRequest.ServicePoint.Expect100Continue = false; 115 116 if (method == Method.POST) 117 { 118 webRequest.ContentType = "application/x-www-form-urlencoded"; 119 requestWriter = new StreamWriter(webRequest.GetRequestStream()); 120 try 121 { 122 requestWriter.Write(postData); 123 } 124 catch 125 { 126 throw; 127 } 128 finally 129 { 130 requestWriter.Close(); 131 requestWriter = null; 132 } 133 } 134 135 responseData = _WebResponseGet(webRequest); 136 137 webRequest = null; 138 139 return responseData; 140 141 } 142 143 private string _WebResponseGet(HttpWebRequest webRequest) 144 { 145 StreamReader responseReader = null; 146 string responseData = ""; 147 try 148 { 149 responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream()); 150 responseData = responseReader.ReadToEnd(); 151 } 152 catch 153 { 154 throw; 155 } 156 finally 157 { 158 webRequest.GetResponse().GetResponseStream().Close(); 159 responseReader.Close(); 160 responseReader = null; 161 } 162 163 return responseData; 164 } 165 } 166 167 /// <summary> 168 /// 通过code获取access_token 请求成功的实体 169 /// </summary> 170 public class WeiXinAccessTokenModel 171 { 172 /// <summary> 173 /// 接口调用凭证 174 /// </summary> 175 public string access_token { get; set; } 176 /// <summary> 177 /// access_token接口调用凭证超时时间,单位(秒) 178 /// </summary> 179 public int expires_in { get; set; } 180 /// <summary> 181 /// 用户刷新access_token 182 /// </summary> 183 public string refresh_token { get; set; } 184 /// <summary> 185 /// 授权用户唯一标识 186 /// </summary> 187 public string openid { get; set; } 188 /// <summary> 189 /// 用户授权的作用域,使用逗号(,)分隔 190 /// </summary> 191 public string scope { get; set; } 192 } 193 194 public class WeiXinAccessTokenResult 195 { 196 public WeiXinAccessTokenModel SuccessResult { get; set; } 197 public bool Result { get; set; } 198 199 public WeiXinHelper.WeiXinErrorMsg ErrorResult { get; set; } 200 } 201 202 /// <summary> 203 /// 微信帮助类 204 /// </summary> 205 public class WeiXinHelper 206 { 207 /// <summary> 208 /// 微信错误访问的情况 209 /// </summary> 210 public class WeiXinErrorMsg 211 { 212 /// <summary> 213 /// 错误编号 214 /// </summary> 215 public int errcode { get; set; } 216 /// <summary> 217 /// 错误提示消息 218 /// </summary> 219 public string errmsg { get; set; } 220 } 221 222 /// <summary> 223 /// 获取微信用户信息 224 /// </summary> 225 public class WeiXinUserInfoResult 226 { 227 /// <summary> 228 /// 微信用户信息 229 /// </summary> 230 public WeiXinUserInfo UserInfo { get; set; } 231 /// <summary> 232 /// 结果 233 /// </summary> 234 public bool Result { get; set; } 235 /// <summary> 236 /// 错误信息 237 /// </summary> 238 public WeiXinErrorMsg ErrorMsg { get; set; } 239 } 240 241 /// <summary> 242 /// 微信授权成功后,返回的用户信息 243 /// </summary> 244 public class WeiXinUserInfo 245 { 246 /// <summary> 247 /// 用户的唯一标识 248 /// </summary> 249 public string openid { get; set; } 250 /// <summary> 251 /// 用户昵称 252 /// </summary> 253 public string nickname { get; set; } 254 /// <summary> 255 /// 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 256 /// </summary> 257 public string sex { get; set; } 258 /// <summary> 259 /// 用户个人资料填写的省份 260 /// </summary> 261 public string province { get; set; } 262 /// <summary> 263 /// 普通用户个人资料填写的城市 264 /// </summary> 265 public string city { get; set; } 266 /// <summary> 267 /// 国家,如中国为CN 268 /// </summary> 269 public string country { get; set; } 270 /// <summary> 271 /// 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 272 /// </summary> 273 public string headimgurl { get; set; } 274 /// <summary> 275 /// 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom) 276 /// </summary> 277 public string[] privilege { get; set; } 278 /// <summary> 279 /// 用户统一标识,针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的 280 /// </summary> 281 public string unionid { get; set; } 282 } 283 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!