开放平台之⽹站授权登录功能
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 = _config(2);
string send_url = "api.weixin.qq/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 = _config(2);
string send_url = "api.weixin.qq/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 = _config(2);
string send_url = "api.weixin.qq/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 = _config(2);
string send_url =
"api.weixin.qq/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 = _config(2);
//发送并接受返回值
string send_url = "api.weixin.qq/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 = _config(2); //主键id
if (config == null)
{
return Content("出错了,您尚未配置相关的API信息!");
}
string state = Guid.NewGuid().ToString().Replace("-", "");
Session["oauth_state"] = state;
string send_url =
"open.weixin.qq/connect/qrconnect?appid=" + config.oauth_app_id +
"&redirect_uri=" + Utils.urn_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 = _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 = _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 = _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 = _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