微信开放平台之网站授权微信登录功能
程序员文章站
2023-11-14 19:17:16
1 微信开放平台:
2 微信官方教程:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_lis...
1 微信开放平台:
3.pc页面显示
4. 通过官方提供的文档,我们可以看出一共分4个步骤
第一步:请求code
第二步:通过code获取access_token
第三步:通过access_token调用接口
第4步:获取用户个人信息(unionid机制)
api:核心代码
public class weixin_helper { public weixin_helper() { } /// <summary> /// 根据appid和appsecret获得access token(默认过期时间为2小时) /// </summary> /// <returns>dictionary</returns> public static dictionary<string, object> get_access_token() { //获得配置信息 oauth_config config = oauth_helper.get_config(2); string send_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + config.oauth_app_id + "&secret=" + config.oauth_app_key + ""; //发送并接受返回值 string result = utils.httpget(send_url); if (result.contains("errmsg")) { return null; } try { dictionary<string, object> dic = jsonconvert.deserializeobject<dictionary<string, object>>(result); return dic; } catch { return null; } } /// <summary> /// 取得临时的access token(默认过期时间为2小时) /// </summary> /// <param name="code">临时authorization code</param> /// <param name="state">防止csrf攻击,成功授权后回调时会原样带回</param> /// <returns>dictionary</returns> public static dictionary<string, object> get_access_token(string code, string state) { //获得配置信息 oauth_config config = oauth_helper.get_config(2); string send_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + config.oauth_app_id + "&secret=" + config.oauth_app_key + "&code="+code+"&grant_type=authorization_code"; //发送并接受返回值 string result = utils.httpget(send_url); if (result.contains("errmsg")) { return null; } try { dictionary<string, object> dic = jsonconvert.deserializeobject<dictionary<string, object>>(result); return dic; } catch { return null; } } /// <summary> /// 根据access_token判断access_token是否过期 /// </summary> /// <param name="access_token"></param> /// <returns>true表示未失效</returns> public static bool check_access_token(string access_token) { //获得配置信息 oauth_config config = oauth_helper.get_config(2); string send_url = "https://api.weixin.qq.com/sns/auth?access_token=" + access_token + "&openid=" + config.oauth_app_id; //发送并接受返回值 string result = utils.httpget(send_url); try { dictionary<string, object> dic = jsonconvert.deserializeobject<dictionary<string, object>>(result); if (dic.containskey("errmsg")) { if (dic["errmsg"].tostring()=="ok") { return true; } else { return false; } } return false; } catch { return false; } } /// <summary> /// 若fresh_token已过期则根据refresh_token取得新的refresh_token /// </summary> /// <param name="refresh_token">refresh_token</param> /// <returns>dictionary</returns> public static dictionary<string, object> get_refresh_token(string refresh_token) { //获得配置信息 oauth_config config = oauth_helper.get_config(2); string send_url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + config.oauth_app_id + "&grant_type=refresh_token&refresh_token=" + refresh_token; //发送并接受返回值 string result = utils.httpget(send_url); if (result.contains("errmsg")) { return null; } try { dictionary<string, object> dic = jsonconvert.deserializeobject<dictionary<string, object>>(result); return dic; } catch { return null; } } /// <summary> /// 获取登录用户自己的基本资料 /// </summary> /// <param name="access_token">临时的access token</param> /// <param name="open_id">用户openid</param> /// <returns>dictionary</returns> public static dictionary<string, object> get_user_info(string access_token, string open_id) { //获得配置信息 oauth_config config = oauth_helper.get_config(2); //发送并接受返回值 string send_url = "https://api.weixin.qq.com/sns/userinfo?access_token="+access_token+"&openid="+open_id; //发送并接受返回值 string result = utils.httpget(send_url); if (result.contains("errmsg")) { return null; } //反序列化json dictionary<string, object> dic = jsonhelper.datarowfromjson(result); return dic; } }
控制器的核心代码:
#region 微信登录 /// <summary> /// 微信登录 /// </summary> public actionresult wechat() { //获得配置信息 oauth_config config = oauth_helper.get_config(2); //主键id if (config == null) { return content("出错了,您尚未配置微信相关的api信息!"); } string state = guid.newguid().tostring().replace("-", ""); session["oauth_state"] = state; string send_url = "https://open.weixin.qq.com/connect/qrconnect?appid=" + config.oauth_app_id + "&redirect_uri=" + utils.urlencode(config.return_uri.tolower()) + "&response_type=code&scope=snsapi_login&state=" + state + "#wechat_redirect"; //开始发送 return redirect(send_url); //跳转到微信自己 指定的关联登陆页面 } /// <summary> /// 微信登录返回action /// </summary> public actionresult wechatreturnurl(string state, string code) { //取得返回参数 string access_token = string.empty; string expires_in = string.empty; string client_id = string.empty; string openid = string.empty; string refresh_token = string.empty; if (session["oauth_state"] == null || session["oauth_state"].tostring() == "" || state != session["oauth_state"].tostring() || string.isnullorempty(code))//若返回参数中未包含code或者state没有通过验证则提示出错 { return content("出错啦,state未初始化!"); } //第一步:通过code来获取access token以及openid dictionary<string, object> dic1 = weixin_helper.get_access_token(code, state); if (dic1 == null || !dic1.containskey("access_token")) { return content("错误代码:,无法获取access token,请检查app key是否正确!"); } if (dic1 == null || !dic1.containskey("openid")) { if (dic1.containskey("errmsg")) { return content("errcode:" + dic1["errcode"] + ",errmsg:" + dic1["errmsg"]); } else { return content("出错啦,无法获取用户授权openid!"); } } access_token = dic1["access_token"].tostring();//获取access_token expires_in = dic1["expires_in"].tostring();//获取过期时间 refresh_token = dic1["refresh_token"].tostring();//获取用于重新刷新access_token的凭证 openid = dic1["openid"].tostring();//用户唯一标示openid //储存获取数据用到的信息 session["oauth_name"] = "webchat"; session["oauth_access_token"] = access_token; session["oauth_openid"] = openid; session["oauth_refresh_token"] = refresh_token; #region todo 将获取到的用户信息保存到数据库中 #endregion //第二步:通过access token以及openid来获取用户的基本信息 //dictionary<string, object> dic2 = weixin_helper.get_user_info(access_token,openid); //第三步:跳转到指定页面 return content(wechatresultjson()); } /// <summary> /// 微信登录返回action, 处理用户信息 /// </summary> public string wechatresultjson() { string oauth_access_token = string.empty; string oauth_openid = string.empty; string oauth_name = string.empty; string oauth_refresh_token = string.empty; if (session["oauth_name"] == null || session["oauth_access_token"] == null || session["oauth_openid"] == null) { return "{\"ret\":\"1\", \"msg\":\"出错啦,access token已过期或不存在!\"}"; } oauth_name = session["oauth_name"].tostring(); oauth_access_token = session["oauth_access_token"].tostring(); oauth_openid = session["oauth_openid"].tostring(); oauth_refresh_token = session["oauth_refresh_token"].tostring(); if (!weixin_helper.check_access_token(oauth_access_token)) //调用access_token前需判断是否过期 { dictionary<string, object> dic1 = weixin_helper.get_refresh_token(oauth_refresh_token);//如果已过期则重新换取新的access_token if (dic1 == null || !dic1.containskey("access_token")) { return "{\"openid\":\"0\", \"msg\":\"出错啦,无法获取access_token!\"}"; } oauth_access_token = dic1["access_token"].tostring(); } dictionary<string, object> dic = weixin_helper.get_user_info(oauth_access_token, oauth_openid); if (dic == null) { return "{\"openid\":\"0\", \"msg\":\"出错啦,无法获取授权用户信息!\"}"; } try { stringbuilder str = new stringbuilder(); str.append("{"); str.append("\"openid\": \"" + dic["openid"].tostring() + "\", "); str.append("\"nickname\": \"" + dic["nickname"].tostring() + "\", "); str.append("\"sex\": \"" + dic["sex"].tostring() + "\", "); str.append("\"province\": \"" + dic["province"].tostring() + "\", "); str.append("\"city\": \"" + dic["city"].tostring() + "\", "); str.append("\"country\": \"" + dic["country"].tostring() + "\", "); str.append("\"headimgurl\": \"" + dic["headimgurl"].tostring() + "\", "); str.append("\"privilege\": \"" + dic["privilege"].tostring() + "\", "); str.append("\"unionid\": \"" + dic["unionid"].tostring() + "\""); str.append("\"oauth_name\": \"" + oauth_name + "\""); str.append("\"oauth_access_token\": \"" + oauth_access_token + "\""); str.append("\"oauth_openid\": \"" + oauth_openid + "\""); str.append("}"); return str.tostring(); } catch { return "{\"ret\":\"0\", \"msg\":\"出错啦,无法获取授权用户信息!\"}"; } } #endregion
上一篇: C#计算程序执行过程花费时间的方法
下一篇: 如何利用c#实现通用守护进程