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 }