首先我们通过一张图片来了解一下OAuth2.0的运作模式:

从上图我们可以看到,整个过程进行了2次“握手”,最终利用授权的AccessToken进行一系列的请求,相关的过程说明如下:
了解了OAuth2.0的基本原理之后,我们来看一下OAuth2.0在微信中是如何运用的。
假设一个场景:用户进入了一个微信公众账号,随后通过消息中的链接,在微信内嵌浏览器中打开了一个游戏网页,这个游戏需要用户登录并且记录用户的游戏得分。
这种情况下我们有两种处理方式:
可以看出,使用OAuth2.0大幅度提高了用户体验,并且可以自动绑定识别用户微信OpenId。
需要注意的是,上面提到的“OAuth2.0授权页面”还有两种形式:
也就是说,snsapi_base的方法可以“神不知鬼不觉”地获取用户OpenId,全自动完成登录注册过程,但是信息量有限;snsapi_userinfo需要用户在指定界面上授权之后,自动完成整个过程,这个授权有一个时间段,超过时间后需要重新询问用户。
源文件文件夹:Senparc.Weixin.MP/AdvancedAPIs/OAuth
相比其他接口OAuth2.0略微复杂,相关内容将在下一篇专门进行介绍:Senparc.Weixin.MP SDK 微信公众平台开发教程(十二):OAuth2.0说明
源代码中相关方法如下:
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,以及对应视图的代码。


系列教程索引:http://www.cnblogs.com/szw/archive/2013/05/14/weixin-course-index.html
Senparc.Weixin.MP SDK 微信公众平台开发教程(十二):OAuth2.0说明
原文:http://www.cnblogs.com/Alex80/p/4261527.html