网页受权是:应用或者网站请求你用你的微信账号登陆,赞成以后第三方应用能够获取你的我的信息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来跳过受权