网站微信登录授权 ASP.NET
微信认证流程(我自己简称三次握手):
1、用户同意授权,获取code
2、通过code换取网页授权access_token,用户openId等信息
3、通过access_token和用户的openId获取该用户的用户信息
因为第一步必须要经过微信的登录授权,不能网页后端请求,所以先要经过用户同意,通过页面网页请求组装的微信请求链接。请求该链接,
获取code后,后端模拟请求。获取用户信息。
微信三次握手的方法(代码)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
public class WeiXinOAuth { /// <summary> /// 获取微信Code /// </summary> /// <param name="appId">微信AppId</param> /// <param name="appSecret">微信AppSecret</param> /// <param name="redirectUrl">返回的登录地址,要进行Server.Un编码</param> /// <param name="isWap">true=微信内部登录 false=pc网页登录</param> public string GetWeiXinCode( string appId, string appSecret, string redirectUrl, bool isWap) { var r = new Random(); //微信登录授权 //string url = "https://open.weixin.qq.com/connect/qrconnect?appid=" + appId + "&redirect_uri=" + redirectUrl +"&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect"; //微信OpenId授权 //string url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + redirectUrl +"&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect"; //微信用户信息授权 var url= "" ; if (isWap) { url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + redirectUrl + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect" ; } else { url = "https://open.weixin.qq.com/connect/qrconnect?appid=" + appId + "&redirect_uri=" + redirectUrl + "&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect" ; } return url; } /// <summary> /// 通过code获取access_token /// </summary> /// <param name="appId"></param> /// <param name="appSecret"></param> /// <param name="code"></param> /// <returns></returns> public WeiXinAccessTokenResult GetWeiXinAccessToken( string appId, string appSecret, string code) { string url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code" ; string jsonStr = UtilsHelper.GetHttp(url); var result = new WeiXinAccessTokenResult(); if (jsonStr.Contains( "errcode" )) { var errorResult = JsonHelper.JsonDeserialize<WeiXinHelper.WeiXinErrorMsg>(jsonStr); result.ErrorResult = errorResult; result.Result = false ; } else { var model = JsonHelper.JsonDeserialize<WeiXinAccessTokenModel>(jsonStr); result.SuccessResult = model; result.Result = true ; } return result; } /// <summary> /// 拉取用户信息 /// </summary> /// <param name="accessToken"></param> /// <param name="openId"></param> /// <returns></returns> public WeiXinHelper.WeiXinUserInfoResult GetWeiXinUserInfo( string accessToken, string openId) { string url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openId + "⟨=zh_CN" ; string jsonStr = UtilsHelper.GetHttp(url); var result = new WeiXinHelper.WeiXinUserInfoResult(); if (jsonStr.Contains( "errcode" )) { var errorResult = JsonHelper.JsonDeserialize<WeiXinHelper.WeiXinErrorMsg>(jsonStr); result.ErrorMsg = errorResult; result.Result = false ; } else { var userInfo = JsonHelper.JsonDeserialize<WeiXinHelper.WeiXinUserInfo>(jsonStr); result.UserInfo = userInfo; result.Result = true ; } return result; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
/// <summary> /// 通过code获取access_token 请求成功的实体 /// </summary> public class WeiXinAccessTokenModel { /// <summary> /// 接口调用凭证 /// </summary> public string access_token { get ; set ; } /// <summary> /// access_token接口调用凭证超时时间,单位(秒) /// </summary> public int expires_in { get ; set ; } /// <summary> /// 用户刷新access_token /// </summary> public string refresh_token { get ; set ; } /// <summary> /// 授权用户唯一标识 /// </summary> public string openid { get ; set ; } /// <summary> /// 用户授权的作用域,使用逗号(,)分隔 /// </summary> public string scope { get ; set ; } } |
1
2
3
4
5
6
7
|
public class WeiXinAccessTokenResult { public WeiXinAccessTokenModel SuccessResult { get ; set ; } public bool Result { get ; set ; } public WeiXinHelper.WeiXinErrorMsg ErrorResult { get ; set ; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
/// <summary> /// 微信帮助类 /// </summary> public class WeiXinHelper { /// <summary> /// 微信错误访问的情况 /// </summary> public class WeiXinErrorMsg { /// <summary> /// 错误编号 /// </summary> public int errcode { get ; set ; } /// <summary> /// 错误提示消息 /// </summary> public string errmsg { get ; set ; } } /// <summary> /// 获取微信用户信息 /// </summary> public class WeiXinUserInfoResult { /// <summary> /// 微信用户信息 /// </summary> public WeiXinUserInfo UserInfo { get ; set ; } /// <summary> /// 结果 /// </summary> public bool Result { get ; set ; } /// <summary> /// 错误信息 /// </summary> public WeiXinErrorMsg ErrorMsg { get ; set ; } } /// <summary> /// 微信授权成功后,返回的用户信息 /// </summary> public class WeiXinUserInfo { /// <summary> /// 用户的唯一标识 /// </summary> public string openid { get ; set ; } /// <summary> /// 用户昵称 /// </summary> public string nickname { get ; set ; } /// <summary> /// 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 /// </summary> public string sex { get ; set ; } /// <summary> /// 用户个人资料填写的省份 /// </summary> public string province { get ; set ; } /// <summary> /// 普通用户个人资料填写的城市 /// </summary> public string city { get ; set ; } /// <summary> /// 国家,如中国为CN /// </summary> public string country { get ; set ; } /// <summary> /// 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 /// </summary> public string headimgurl { get ; set ; } /// <summary> /// 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom) /// </summary> public string [] privilege { get ; set ; } } } |
以上代码,直接在一个类库里面建相应的类就可以,直接封装就ok
下面是前台使用的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
//获取appId,appSecret的配置信息 string appId = ConfigHelper.GetConfigString( "WwAppId" ); string appSecret = ConfigHelper.GetConfigString( "WwAppSecret" ); var weixinOAuth = new WeiXinOAuth(); //微信第一次握手后得到的code 和state string code = FytRequest.GetQueryString( "code" ); string state = FytRequest.GetQueryString( "state" ); if (code == "" || code == "authdeny" ) { if (code == "" ) { //发起授权(第一次微信握手) string authUrl = weixinOAuth.GetWeiXinCode(appId, appSecret, Server.UrlEncode(Request.Url.ToString()), true ); Response.Redirect(authUrl, true ); } else { // 用户取消授权 Response.Redirect( "~/Error.html" , true ); } } else { //获取微信的Access_Token(第二次微信握手) var modelResult = weixinOAuth.GetWeiXinAccessToken(appId, appSecret, code); //获取微信的用户信息(第三次微信握手) var userInfo = weixinOAuth.GetWeiXinUserInfo(modelResult.SuccessResult.access_token, modelResult.SuccessResult.openid); //用户信息(判断是否已经获取到用户的微信用户信息) if (userInfo.Result && userInfo.UserInfo.openid != "" ) { //根据OpenId判断数据库是否存在,如果存在,直接登录即可 var oauthUser = OperateContext<tb_UserLoginOauth>.SetServer.GetModel(m => m.OpenId == userInfo.UserInfo.openid); if (oauthUser != null ) { //直接登录即可 根据授权ID,查询用户信息 if (HttpContext.Session != null ) HttpContext.Session[ "FytUser" ] = oauthUser.tb_User; UtilsHelper.WriteCookie( "FytUserId" , DESEncrypt.Encrypt(oauthUser.tb_User.ID.ToString(CultureInfo.InvariantCulture))); } else { //注册操作 OauthReg(userInfo); } //授权成功后,直接返回到首页 return RedirectToAction( "Index" , "MHome" ); } else { return Content( "授权失败,请返回重新操作!" ); } } |