最新做一些項目都有微信登錄注冊什么的,今天就把自己整理的demo提供給大家
微信認證流程(我自己簡稱三次握手):
1、用戶同意授權,獲取code
2、通過code換取網頁授權access_token,用戶openId等信息
3、通過access_token和用戶的openId獲取該用戶的用戶信息
因為第一步必須要經過微信的登錄授權,不能網頁后端請求,所以先要經過用戶同意,通過頁面網頁請求組裝的微信請求鏈接。請求該鏈接,
獲取code后,后端模擬請求。獲取用戶信息。
微信三次握手的方法(代碼)
public class WeiXinOAuth { /// <summary> /// 獲取微信Code /// </summary> /// <param name="appId">微信AppId</param> /// <param name="appSecret">微信AppSecret</param> /// <param name="redirectUrl">返回的登錄地址,要進行Server.Un編碼</param> /// <param name="isWap">true=微信內部登錄 false=pc網頁登錄</param> public string GetWeiXinCode(string appId, string appSecret, string redirectUrl,bool isWap) { var r = new Random(); //微信登錄授權 //string url = "https://open.weixin.qq.com/connect/qrconnect?appid=" + appId + "&redirect_uri=" + redirectUrl +"&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect"; //微信OpenId授權 //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"; //微信用戶信息授權 var url=""; if (isWap) { url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + redirectUrl + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"; } else { url = "https://open.weixin.qq.com/connect/qrconnect?appid=" + appId + "&redirect_uri=" + redirectUrl + "&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect"; } return url; } /// <summary> /// 通過code獲取access_token /// </summary> /// <param name="appId"></param> /// <param name="appSecret"></param> /// <param name="code"></param> /// <returns></returns> public WeiXinAccessTokenResult GetWeiXinAccessToken(string appId, string appSecret, string code) { string url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code"; string jsonStr = UtilsHelper.GetHttp(url); var result = new WeiXinAccessTokenResult(); if (jsonStr.Contains("errcode")) { var errorResult = JsonHelper.JsonDeserialize<WeiXinHelper.WeiXinErrorMsg>(jsonStr); result.ErrorResult = errorResult; result.Result = false; } else { var model = JsonHelper.JsonDeserialize<WeiXinAccessTokenModel>(jsonStr); result.SuccessResult = model; result.Result = true; } return result; } /// <summary> /// 拉取用戶信息 /// </summary> /// <param name="accessToken"></param> /// <param name="openId"></param> /// <returns></returns> public WeiXinHelper.WeiXinUserInfoResult GetWeiXinUserInfo(string accessToken, string openId) { string url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openId + "⟨=zh_CN"; string jsonStr = UtilsHelper.GetHttp(url); var result = new WeiXinHelper.WeiXinUserInfoResult(); if (jsonStr.Contains("errcode")) { var errorResult = JsonHelper.JsonDeserialize<WeiXinHelper.WeiXinErrorMsg>(jsonStr); result.ErrorMsg = errorResult; result.Result = false; } else { var userInfo = JsonHelper.JsonDeserialize<WeiXinHelper.WeiXinUserInfo>(jsonStr); result.UserInfo = userInfo; result.Result = true; } return result; }
/// <summary> /// 通過code獲取access_token 請求成功的實體 /// </summary> public class WeiXinAccessTokenModel { /// <summary> /// 接口調用憑證 /// </summary> public string access_token { get; set; } /// <summary> /// access_token接口調用憑證超時時間,單位(秒) /// </summary> public int expires_in { get; set; } /// <summary> /// 用戶刷新access_token /// </summary> public string refresh_token { get; set; } /// <summary> /// 授權用戶唯一標識 /// </summary> public string openid { get; set; } /// <summary> /// 用戶授權的作用域,使用逗號(,)分隔 /// </summary> public string scope { get; set; } }
public class WeiXinAccessTokenResult { public WeiXinAccessTokenModel SuccessResult { get; set; } public bool Result { get; set; } public WeiXinHelper.WeiXinErrorMsg ErrorResult { get; set; } }
/// <summary> /// 微信幫助類 /// </summary> public class WeiXinHelper { /// <summary> /// 微信錯誤訪問的情況 /// </summary> public class WeiXinErrorMsg { /// <summary> /// 錯誤編號 /// </summary> public int errcode { get; set; } /// <summary> /// 錯誤提示消息 /// </summary> public string errmsg { get; set; } } /// <summary> /// 獲取微信用戶信息 /// </summary> public class WeiXinUserInfoResult { /// <summary> /// 微信用戶信息 /// </summary> public WeiXinUserInfo UserInfo { get; set; } /// <summary> /// 結果 /// </summary> public bool Result { get; set; } /// <summary> /// 錯誤信息 /// </summary> public WeiXinErrorMsg ErrorMsg { get; set; } } /// <summary> /// 微信授權成功后,返回的用戶信息 /// </summary> public class WeiXinUserInfo { /// <summary> /// 用戶的唯一標識 /// </summary> public string openid { get; set; } /// <summary> /// 用戶昵稱 /// </summary> public string nickname { get; set; } /// <summary> /// 用戶的性別,值為1時是男性,值為2時是女性,值為0時是未知 /// </summary> public string sex { get; set; } /// <summary> /// 用戶個人資料填寫的省份 /// </summary> public string province { get; set; } /// <summary> /// 普通用戶個人資料填寫的城市 /// </summary> public string city { get; set; } /// <summary> /// 國家,如中國為CN /// </summary> public string country { get; set; } /// <summary> /// 用戶頭像,最后一個數值代表正方形頭像大小(有0、46、64、96、132數值可選,0代表640*640正方形頭像),用戶沒有頭像時該項為空 /// </summary> public string headimgurl { get; set; } /// <summary> /// 用戶特權信息,json 數組,如微信沃卡用戶為(chinaunicom) /// </summary> public string[] privilege { get; set; } } }
以上代碼,直接在一個類庫里面建相應的類就可以,直接封裝就ok
下面是前台使用的代碼
//獲取appId,appSecret的配置信息 string appId = ConfigHelper.GetConfigString("WwAppId"); string appSecret = ConfigHelper.GetConfigString("WwAppSecret"); var weixinOAuth = new WeiXinOAuth(); //微信第一次握手后得到的code 和state string code = FytRequest.GetQueryString("code"); string state = FytRequest.GetQueryString("state"); if (code == "" || code == "authdeny") { if (code == "") { //發起授權(第一次微信握手) string authUrl = weixinOAuth.GetWeiXinCode(appId, appSecret, Server.UrlEncode(Request.Url.ToString()),true); Response.Redirect(authUrl, true); } else { // 用戶取消授權 Response.Redirect("~/Error.html", true); } } else { //獲取微信的Access_Token(第二次微信握手) var modelResult = weixinOAuth.GetWeiXinAccessToken(appId, appSecret, code); //獲取微信的用戶信息(第三次微信握手) var userInfo = weixinOAuth.GetWeiXinUserInfo(modelResult.SuccessResult.access_token, modelResult.SuccessResult.openid); //用戶信息(判斷是否已經獲取到用戶的微信用戶信息) if (userInfo.Result && userInfo.UserInfo.openid != "") { //根據OpenId判斷數據庫是否存在,如果存在,直接登錄即可 var oauthUser = OperateContext<tb_UserLoginOauth>.SetServer.GetModel(m => m.OpenId == userInfo.UserInfo.openid); if (oauthUser != null) { //直接登錄即可 根據授權ID,查詢用戶信息 if (HttpContext.Session != null) HttpContext.Session["FytUser"] = oauthUser.tb_User; UtilsHelper.WriteCookie("FytUserId", DESEncrypt.Encrypt(oauthUser.tb_User.ID.ToString(CultureInfo.InvariantCulture))); } else { //注冊操作 OauthReg(userInfo); } //授權成功后,直接返回到首頁 return RedirectToAction("Index", "MHome"); } else { return Content("授權失敗,請返回重新操作!"); } }