微信用户授权登录
后台配置
网页授权域名需要配置
不要在前面加http://
请求网址
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
redirect_uri一定要在前面加http://
(心好累┭┮﹏┭┮)
Tips:此处不加http://,会造成“redirect_uri域名与后台配置不一致,错误码:10003”的错误
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
appid | 是 | 应用唯一标识 |
redirect_uri | 是 | 请使用urlEncode对链接进行处理 |
response_type | 是 | 填code |
scope | 是 | 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可 |
state | 否 | 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 |
使用盛派SDK
仅针对服务号有效,用户可以不关注该服务号而拿到用户信息
需要注意的是,仅这次授权的时候可以拿到用户信息,之后再使用UserApi.InfoAsync()是拿不到用户信息的
(所以孩子们注意保存用户信息,吃过亏的我┭┮﹏┭┮)
添加引用
Senparc.Weixin
Senparc.Weixin.MP.MVC
直接获得openid
下面的例子在授权获得用户信息之后直接返回json字符串
private string authorizeUrl = "域名地址";
private string appId = "";
private string appSecret = "";
//这两个接口都在WeixinController里面
public async Task<ActionResult> GetWechatUserInfoInterface(string returnUrl)
{
var state = "zl-" + DateTime.Now.Millisecond; //随机数,用于识别请求可靠性
Session["zl-weixin-sate"] = state; //储存随机数到Session
var userLogUrl = authorizeUrl + "/weixin/GetWechatUserInfoCallBackInterface?returnUrl=" + returnUrl.UrlEncode();
//微信授权网址
//先调微信的接口,再返回带的自己的接口
var urlUserInfo = OAuthApi.GetAuthorizeUrl(appId, userLogUrl, state, OAuthScope.snsapi_userinfo);
return Redirect(urlUserInfo);
}
/// <summary>
/// 用户验证回掉函数
/// </summary>
/// <returns></returns>
public async Task<ActionResult> GetWechatUserInfoCallBackInterface(string code, string state, string returnUrl)
{
if (string.IsNullOrEmpty(code))
{
return Json("您拒绝了授权!");
}
if (state != Session["zl-weixin-sate"] as string)
{
return Json("验证失败!请从正规途径进入!");
}
try
{
var token = await OAuthApi.GetAccessTokenAsync(appId, appSecret, code);
if (token.errcode == ReturnCode.请求成功)
{
//此处获得用户信息
var oAuthUserInfo = await OAuthApi.GetUserInfoAsync(token.access_token, token.openid);
return Json(JsonConvert.SerializeObject(oAuthUserInfo), JsonRequestBehavior.AllowGet);
}
return Json("请求失败!");
}
catch (Exception ex)
{
return Json("Token授权失败!");
}
}
提供给他人调用
遇到的需求是,对方是个订阅号,想使用我这边的服务号发红包,发红包需要OpenId,而OpenId是针对公众号唯一的,所以必须获得用户针对服务号的OpenId
我们不能把自己的appId和appSecret提供给对方,所以需要给他们写接口
实践发现,上例不适用于提供给他人调用,原因如下:
1.如果前端直接调用接口GetWechatUserInfoInterface,会涉及跨域的问题(当然你们愿意配置也是可以的)
2.如果后端直接调用接口GetWechatUserInfoInterface,微信会认为“没有在微信客户端打开”,即调用微信授权接口时失败
所以可以把上面的例子稍作修改,大概思路是,在我们这边完全完成授权之后再跳转对方的网站,把信息带给他们
private string authorizeUrl = "域名地址";
private string appId = "";
private string appSecret = "";
public async Task<ActionResult> WeiXinRedPackForeignView(string returnUrl)
{
var state = "zl-" + DateTime.Now.Millisecond; //随机数,用于识别请求可靠性
Session["zl-weixin-sate"] = state; //储存随机数到Session
var userLogUrl = authorizeUrl + "/weixin/UserLoginForRedPackForeignInterface?returnUrl=" + returnUrl.UrlEncode();
//微信授权网址
//先调微信的接口,再返回带的自己的接口
var urlUserInfo = OAuthApi.GetAuthorizeUrl(appId, userLogUrl, state, OAuthScope.snsapi_userinfo);
//这里改为返回自己的页面
return View("WeiXinRedPackForeignView", new NameValueDto { Name = urlUserInfo });
}
/// <summary>
/// 用户验证回掉函数
/// </summary>
/// <returns></returns>
public async Task<ActionResult> UserLoginForRedPackForeignInterface(string code, string state, string returnUrl)
{
if (string.IsNullOrEmpty(code))
{
return Json("您拒绝了授权!");
}
if (state != Session["zl-weixin-sate"] as string)
{
return Json("验证失败!请从正规途径进入!");
}
try
{
var token = await OAuthApi.GetAccessTokenAsync(appId, appSecret, code);
if (token.errcode == ReturnCode.请求成功)
{
var oAuthUserInfo = await OAuthApi.GetUserInfoAsync(token.access_token, token.openid);
SaveWeixinUserInfo(oAuthUserInfo);
//这里跳转到对方的页面,带上oAuthUserInfo信息(base64加密)
string url = WebConfigurationManager.AppSettings["RedPackForeignInterUrl"];
byte[] bytes = Encoding.Default.GetBytes(JsonConvert.SerializeObject(oAuthUserInfo));
string base64Str= Convert.ToBase64String(bytes);
return Redirect(url+ base64Str);
}
return Json("请求失败!");
}
catch (Exception ex)
{
return Json("Token授权失败!");
}
}
示例代码
https://github.com/zLulus/NotePractice/blob/dev3/Website/DotNetFramework/NotePractice/Controllers/WeiXinController.cs
演示需要:
请以管理员身份运行VS(会发布站点到IIS上)
给站点配置一个域名,比如花生壳,可以参考我的文 章:https://github.com/zLulus/My_Note/wiki/%E5%BE%AE%E4%BF%A1%E8%B0%83%E8%AF%95%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F
填写好authorizeUrl、appId和appSecret
在公众号设置-功能设置,设置“授权域名”,下载MP_verify_QvGuHOyO3bMD1fLJ.txt到站点根目录
参考资料
学习技术最好的文档就是【官方文档】,没有之一。
还有学习资料【Microsoft Learn】、【CSharp Learn】、【My Note】。
如果,你认为阅读这篇博客让你有些收获,不妨点击一下右下角的【推荐】按钮。
如果,你希望更容易地发现我的新博客,不妨点击一下【关注】。