您好,欢迎访问一九零五行业门户网

微信公众平台开发:OAuth2.0说明

理解oauth2.0
首先我们通过一张图片来了解一下oauth2.0的运作模式:
从上图我们可以看到,整个过程进行了2次“握手”,最终利用授权的accesstoken进行一系列的请求,相关的过程说明如下:
a:由客户端向服务器发出验证请求,请求中一般会携带这些参数
id标识,例如appid
验证后跳转到的url(redirecturl)
状态参数(可选)
授权作用域scope(可选)
响应类型(可选)
b:服务器返回一个grant授权标识(微信默认情况下称之为code),类似于一个一次性的临时字符串密钥。如果在a中提供了redirecturl,这里服务器会做一次跳转,带上grant和状态参数,访问redirecturl。
c:客户端的redirecturl对应页面,凭借grant再次发起请求,这次请求通常会携带一些敏感信息:
id标识
密码
grant字符串(code)
grant类型(可选,微信中默认为code)
d:服务器验证id标识、密码、grant都正确之后,返回accesstoken(注意,这里的accesstoken和之前通用接口、高级接口介绍的accesstoken没有关系,不能交叉使用)
e:客户端凭借accesstoken请求一系列的api,在此过程中不再会携带appid,secret,grant等敏感的信息。
f:服务器返回请求结果。
微信的oauth2.0使用
了解了oauth2.0的基本原理之后,我们来看一下oauth2.0在微信中是如何运用的。
假设一个场景:用户进入了一个微信公众账号,随后通过消息中的链接,在微信内嵌浏览器中打开了一个游戏网页,这个游戏需要用户登录并且记录用户的游戏得分。
这种情况下我们有两种处理方式:
让用户在网页中进行注册、登录(并且每次打开这个网页都可能要重新进行登录,因为微信内置浏览器的cookie保存时间非常短),这个当然是个很坑爹的设计。
利用oauth2.0。在用户进入这个页面的时候,先判断用户是否登录,如果没有,自动跳转到oauth2.0授权页面,这个页面又自动进行了上述abcd一系列验证,再通过ef得到用户的openid甚至更加详细的信息(包括头像),自动完成登录(或必要的注册)过程,随后用户以登录状态直接进入游戏。
可以看出,使用oauth2.0大幅度提高了用户体验,并且可以自动绑定识别用户微信openid。
需要注意的是,上面提到的“oauth2.0授权页面”还有两种形式:
当请求a中的scope为snsapi_base时,整个授权过程自动完成,用户的客户端不会有任何中间页面显示,但是授权的结果仅能获取用户的openid(不管用户是否已关注,当然如果用户是关注用户,再次利用高级接口中的用户信息接口,利用openid获取用户资料也是可以的,只不过绕了几个弯)
当请求a中的scope为snsapi_userinfo时,需要提供一个授权页面(类似很多网站利用微博账号、qq号登陆的那种授权),仅当用户同意之后,立即获取到用户的详细信息,这里的用户可以是关注用户,也可以是未关注用户,返回的内容一致。
也就是说,snsapi_base的方法可以“神不知鬼不觉”地获取用户openid,全自动完成登录注册过程,但是信息量有限;snsapi_userinfo需要用户在指定界面上授权之后,自动完成整个过程,这个授权有一个时间段,超过时间后需要重新询问用户。
senparc.weixin.mp oauth2.0接口
源文件文件夹:senparc.weixin.mp/advancedapis/oauth
源代码中相关方法如下:
namespace senparc.weixin.mp.advancedapis { //官方文档:http://mp.weixin.qq.com/wiki/index.php?title=%e7%bd%91%e9%a1%b5%e6%8e%88%e6%9d%83%e8%8e%b7%e5%8f%96%e7%94%a8%e6%88%b7%e5%9f%ba%e6%9c%ac%e4%bf%a1%e6%81%af#.e7.ac.ac.e4.b8.80.e6.ad.a5.ef.bc.9a.e7.94.a8.e6.88.b7.e5.90.8c.e6.84.8f.e6.8e.88.e6.9d.83.ef.bc.8c.e8.8e.b7.e5.8f.96code /// <summary> /// 应用授权作用域 /// </summary> public enum oauthscope { /// <summary> /// 不弹出授权页面,直接跳转,只能获取用户openid /// </summary> snsapi_base, /// <summary> /// 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息 /// </summary> snsapi_userinfo } public static class oauth { /// <summary> /// 获取验证地址 /// </summary> /// <param name="appid"></param> /// <param name="redirecturl"></param> /// <param name="state"></param> /// <param name="scope"></param> /// <param name="responsetype"></param> /// <returns></returns> public static string getauthorizeurl(string appid, string redirecturl, string state, oauthscope scope, string responsetype = "code") { var url = string.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type={2}&scope={3}&state={4}#wechat_redirect", appid, redirecturl.urlencode(), responsetype, scope, state); /* 这一步发送之后,客户会得到授权页面,无论同意或拒绝,都会返回redirecturl页面。 * 如果用户同意授权,页面将跳转至 redirect_uri/?code=code&state=state。这里的code用于换取access_token(和通用接口的access_token不通用) * 若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=state */ return url; } /// <summary> /// 获取accesstoken /// </summary> /// <param name="appid"></param> /// <param name="secret"></param> /// <param name="code">code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。</param> /// <param name="granttype"></param> /// <returns></returns> public static oauthaccesstokenresult getaccesstoken(string appid, string secret, string code, string granttype = "authorization_code") { var url = string.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type={3}", appid, secret, code, granttype); return commonjsonsend.send<oauthaccesstokenresult>(null, url, null, commonjsonsendtype.get); } /// <summary> /// 刷新access_token(如果需要) /// </summary> /// <param name="appid"></param> /// <param name="refreshtoken">填写通过access_token获取到的refresh_token参数</param> /// <param name="granttype"></param> /// <returns></returns> public static oauthaccesstokenresult refreshtoken(string appid, string refreshtoken, string granttype = "refresh_token") { var url = string.format("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid={0}&grant_type={1}&refresh_token={2}", appid, granttype, refreshtoken); return commonjsonsend.send<oauthaccesstokenresult>(null, url, null, commonjsonsendtype.get); } public static oauthuserinfo getuserinfo(string accesstoken,string openid) { var url = string.format("https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}",accesstoken,openid); return commonjsonsend.send<oauthuserinfo>(null, url, null, commonjsonsendtype.get); } } }
具体的示例方法见senparc.weixin.mp.sample/controllers/oauth2controller.cs,以及对应视图的代码。
注意点
必须是通过认证的服务号才可以使用oauth接口。
接口中用到的accesstoken和高级接口(包括通用接口)中用到的accesstoken互不相关,即使他们都是通过相同的appid和secret得到的。
目前官方的授权页面不是100%稳定,有时候需要多点几次才能顺利通过,如果发现此类情况,需要做一些判断反复请求,至少在表面上可以不让用户看到错误页面。
出于安全,在使用oauth2.0之前,需要进入到微信后台的【我的服务】对回调页面的域名进行设置:
更多微信公众平台开发:oauth2.0说明。
其它类似信息

推荐信息