網頁受權是:應用或者網站請求你用你的微信賬號登陸,贊成以後第三方應用能夠獲取你的我的信息html
網上說了一大堆參數,實際很難理解和猜透,咱們以實際的代碼來演示比較通俗易懂jquery
實現以前咱們必須配置用戶受權獲取用戶信息的域名或者IP。正式公衆號只能配置(域名)數據庫
跟咱們以前配置公衆號平臺信息同樣api
拉到下半部分位置的網頁帳號緩存
咱們模擬一個須要受權的頁面(代碼提供來自Senparc)安全
裏面只有2個方法,一個是Index即須要受權的頁面,第二個是BaseCallback頁面即受權成功後要跳轉的頁面服務器
public class OAuth2Controller : Controller { [Dependency] public IWC_OfficalAccountsBLL account_BLL { get; set; } /// <summary> /// /// </summary> /// <param name="returnUrl">用戶嘗試進入的須要登陸的頁面</param> /// <returns></returns> public ActionResult Index(string returnUrl) { WC_OfficalAccountsModel model = account_BLL.GetCurrentAccount(); //獲取用戶保存的cookie //判斷是否已經受權過 var state = "YMNETS-" + DateTime.Now.Millisecond;//隨機數,用於識別請求可靠性 Session["State"] = state;//儲存隨機數到Session ViewData["returnUrl"] = returnUrl; //此頁面引導用戶點擊受權 ViewData["UrlUserInfo"] = OAuthApi.GetAuthorizeUrl(model.AppId, "http://ymnets.imwork.net/WC/OAuth2/UserInfoCallback?returnUrl=" + returnUrl.UrlEncode(), state, OAuthScope.snsapi_userinfo); ViewData["UrlBase"] = OAuthApi.GetAuthorizeUrl(model.AppSecret, "http://ymnets.imwork.net/WC/OAuth2/BaseCallback?returnUrl=" + returnUrl.UrlEncode(), state, OAuthScope.snsapi_base); return View(); } /// <summary> /// OAuthScope.snsapi_userinfo方式回調 /// </summary> /// <param name="code"></param> /// <param name="state"></param> /// <param name="returnUrl">用戶最初嘗試進入的頁面</param> /// <returns></returns> public ActionResult UserInfoCallback(string code, string state, string returnUrl) { if (string.IsNullOrEmpty(code)) { return Content("您拒絕了受權!"); } if (state != Session["State"] as string) { //這裏的state實際上是會暴露給客戶端的,驗證能力很弱,這裏只是演示一下, //建議用完以後就清空,將其一次性使用 //實際上能夠存任何想傳遞的數據,好比用戶ID,而且須要結合例以下面的Session["OAuthAccessToken"]進行驗證 return Content("驗證失敗!請從正規途徑進入!"); } OAuthAccessTokenResult result = null; //經過,用code換取access_token try { WC_OfficalAccountsModel model = account_BLL.GetCurrentAccount(); result = OAuthApi.GetAccessToken(model.AppId, model.AppSecret, code); } catch (Exception ex) { return Content(ex.Message); } if (result.errcode != ReturnCode.請求成功) { return Content("錯誤:" + result.errmsg); } //下面2個數據也能夠本身封裝成一個類,儲存在數據庫中(建議結合緩存) //若是能夠確保安全,能夠將access_token存入用戶的cookie中,每個人的access_token是不同的 Session["OAuthAccessTokenStartTime"] = DateTime.Now; Session["OAuthAccessToken"] = result; //由於第一步選擇的是OAuthScope.snsapi_userinfo,這裏能夠進一步獲取用戶詳細信息 try { if (!string.IsNullOrEmpty(returnUrl)) { return Redirect(returnUrl); } OAuthUserInfo userInfo = OAuthApi.GetUserInfo(result.access_token, result.openid); return View(userInfo); } catch (ErrorJsonResultException ex) { return Content(ex.Message); } } } }
獲取接口的方法微信
/*此接口不提供異步方法*/ /// <summary> /// 獲取驗證地址 /// </summary> /// <param name="appId">公衆號的惟一標識</param> /// <param name="redirectUrl">受權後重定向的回調連接地址,請使用urlencode對連接進行處理</param> /// <param name="state">重定向後會帶上state參數,開發者能夠填寫a-zA-Z0-9的參數值,最多128字節</param> /// <param name="scope">應用受權做用域,snsapi_base (不彈出受權頁面,直接跳轉,只能獲取用戶openid),snsapi_userinfo (彈出受權頁面,可經過openid拿到暱稱、性別、所在地。而且,即便在未關注的狀況下,只要用戶受權,也能獲取其信息)</param> /// <param name="responseType">返回類型,請填寫code(或保留默認)</param> /// <param name="addConnectRedirect">加上後能夠解決40029-invalid code的問題(測試中)</param> /// <returns></returns> public static string GetAuthorizeUrl(string appId, string redirectUrl, string state, OAuthScope scope, string responseType = "code", bool addConnectRedirect = true) { var url = string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type={2}&scope={3}&state={4}{5}#wechat_redirect", appId.AsUrlData(), redirectUrl.AsUrlData(), responseType.AsUrlData(), scope.ToString("g").AsUrlData(), state.AsUrlData(), addConnectRedirect ? "&connect_redirect=1" : ""); /* 這一步發送以後,客戶會獲得受權頁面,不管贊成或拒絕,都會返回redirectUrl頁面。 * 若是用戶贊成受權,頁面將跳轉至 redirect_uri/?code=CODE&state=STATE。這裏的code用於換取access_token(和通用接口的access_token不通用) * 若用戶禁止受權,則重定向後不會帶上code參數,僅會帶上state參數redirect_uri?state=STATE */ return url; }
經過這個接口就能夠組成調用微信API的參數cookie
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>OAuth2.0受權測試</title> <style> .green { color: green; } </style> @Scripts.Render("~/bundles/modernizr") @Scripts.Render("~/bundles/jquery") </head> <body> <h2>OAuth2.0受權測試</h2> <p>注意:此頁面僅供測試,測試號隨時可能過時。請將此DEMO部署到您本身的服務器上,並使用本身的appid和secret。</p> <p> 當前returnUrl: @if (ViewData["returnUrl"] == null || ViewData["returnUrl"] as string == "") { <span> <strong>不帶returnUrl</strong>。 </span><br /> <span class="green">使用不帶returnUrl的頁面會停留在Callback頁面,此頁面若是刷新(或後退到此頁面),會致使code過時的錯誤,只建議在測試階段使用。</span> <br/> <span> 測試帶returnUrl@(Html.ActionLink("點擊這裏", "Index", new { returnUrl = Url.Action("TestReturnUrl") }))。 </span> } else { <span><strong>@ViewData["returnUrl"]</strong>。</span><br /> <span class="green">攜帶returnUrl後,頁面最終會跳轉到returnUrl對應頁面,避免刷新頁面致使code的錯誤。</span> } </p> <p><a href="@ViewData["UrlUserInfo"]">點擊這裏測試snsapi_userinfo</a></p> <p> 將要連接到的地址:<br /> <textarea rows="10" cols="40">@ViewData["UrlUserInfo"]</textarea> </p> <p><a href="@ViewData["UrlBase"]">點擊這裏測試snsapi_base</a></p> <p> 將要連接到的地址:<br /> <textarea rows="10" cols="40">@ViewData["UrlBase"]</textarea> </p> </body> </html>
@model Senparc.Weixin.MP.AdvancedAPIs.OAuth.OAuthUserInfo @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>OAuth2.0受權測試受權成功</title> </head> <body> <h2>OAuth2.0受權測試受權成功!</h2> @if (ViewData.ContainsKey("ByBase")) { <p><strong>您看到的這個頁面來自於snsapi_base受權,由於您已關注本微信,因此才能查詢到詳細用戶信息,不然只能進行常規的受權。</strong></p> } else { <p><strong>您看到的這個頁面來自於snsapi_userinfo受權,能夠直接獲取到用戶詳細信息。</strong></p> } <p>下面是經過受權獲得的您的部分我的信息:</p> <p>openid:@Model.openid</p> <p>nickname:@Model.nickname</p> <p>country:@Model.country</p> <p>province:@Model.province</p> <p>city:@Model.city</p> <p>sex:@Model.sex</p> @if (Model.unionid != null) { <p>unionid:@Model.unionid</p> } <p> 頭像:<br /> <img src="@Model.headimgurl" style="width: 50%"/>(直接調用可能看不到,須要抓取) </p> </body> </html>
在公衆號裏面調用這個連接,咱們在圖文回覆中,設置一個連接是指向這個受權頁面的測試一下,即:app
http://ymnets.imwork.net/WC/OAuth2/Index?returnUrl=http://ymnets.imwork.net/WC/OAuth2/UserInfoCallBack
理論是隻要能經過微信打開這個連接就好,什麼方式都是能夠的
注意格式:retuenUrl是校驗成功要返回的Url地址
----------------------------------演示開始--------------------------------------
成功後獲取用戶信息
----------------------------------演示結束--------------------------------------
受權以後咱們應該利用cookie來記錄用戶登陸情況,下次登陸時候判斷是否有cookie來跳過受權