微信用户授权登录

后台配置

网页授权域名需要配置
不要在前面加http://
1

请求网址

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到站点根目录

参考资料

https://www.jianshu.com/p/5b5c2131bff9

posted @ 2018-01-22 21:09  Lulus  阅读(528)  评论(0编辑  收藏  举报