ASP.NET MVC5+EF6+EasyUI 後臺管理系統(76)-微信公衆平臺開發-網頁受權

 前言

網頁受權是:應用或者網站請求你用你的微信賬號登陸,贊成以後第三方應用能夠獲取你的我的信息html

網上說了一大堆參數,實際很難理解和猜透,咱們以實際的代碼來演示比較通俗易懂jquery

 

配置

實現以前咱們必須配置用戶受權獲取用戶信息的域名或者IP。正式公衆號只能配置(域名)數據庫

第一步:登陸公衆號平臺

跟咱們以前配置公衆號平臺信息同樣api

第二步: 打開開發者工具

拉到下半部分位置的網頁帳號緩存

 第三步:配置你的受權回調域名

實現

咱們模擬一個須要受權的頁面(代碼提供來自Senparc)安全

第一步:新建一個Controller

裏面只有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>
Index
@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>
UserInfoCallback

第三步:測試(必須在微信裏面測試)

在公衆號裏面調用這個連接,咱們在圖文回覆中,設置一個連接是指向這個受權頁面的測試一下,即:app

http://ymnets.imwork.net/WC/OAuth2/Index?returnUrl=http://ymnets.imwork.net/WC/OAuth2/UserInfoCallBack

理論是隻要能經過微信打開這個連接就好,什麼方式都是能夠的

注意格式:retuenUrl是校驗成功要返回的Url地址

----------------------------------演示開始--------------------------------------

 

 

成功後獲取用戶信息

----------------------------------演示結束--------------------------------------

總結

受權以後咱們應該利用cookie來記錄用戶登陸情況,下次登陸時候判斷是否有cookie來跳過受權

相關文章
相關標籤/搜索