2018-07-16  1,191 views 评论

ASP.NET WebApi作服务端开发小程序实现微信授权用户登录实例——后台API编写(二)

上一篇“ASP.NET WebApi作服务端开发小程序实现微信授权用户登录实例(一)”中大致讲到小程序中使用微信授权登录的大致流程和前台JS请求逻辑相关代码。

本篇主要讲初次用户登录若用户不存在的情况下 默认添加当前微信授权用户作为站点用户的开发过程(大部分为API,因为请求已经在上一篇中写了)

第一步:首先需要准备相关的辅助类和基础模型类:

1)辅助类GetUsersHelper 帮助类

/// <summary>
/// 获取用户帮助类
/// </summary>
public class GetUsersHelper
{
    /// <summary> 
    /// 获取链接返回数据 
    /// </summary> 
    /// <param name="Url">链接</param> 
    /// <param name="type">请求类型</param> 
    /// <returns></returns> 
    public string GetUrltoHtml(string Url, string type)
    {
        try
        {
            System.Net.WebRequest wReq = System.Net.WebRequest.Create(Url);
            System.Net.WebResponse wResp = wReq.GetResponse();
            System.IO.Stream respStream = wResp.GetResponseStream();
            using (System.IO.StreamReader reader = new System.IO.StreamReader(respStream, Encoding.GetEncoding(type)))
            {
                return reader.ReadToEnd();
            }
        }
        catch (System.Exception ex)
        {
            return ex.Message;
        }
    }
    #region 微信小程序用户数据解密 
    /// <summary>
    /// AES Key
    /// </summary>
    public static string AesKey;
    /// <summary>
    /// AES IV
    /// </summary>
    public static string AesIV;

    /// <summary> 
    /// AES解密 
    /// </summary> 
    /// <param name="inputdata">输入的数据encryptedData</param> 
    /// <returns name="result">解密后的字符串</returns> 
    public string AESDecrypt(string inputdata)
    {
        try
        {
            AesIV = AesIV.Replace(" ", "+");
            AesKey = AesKey.Replace(" ", "+");
            inputdata = inputdata.Replace(" ", "+");
            byte[] encryptedData = Convert.FromBase64String(inputdata);

            RijndaelManaged rijndaelCipher = new RijndaelManaged();
            rijndaelCipher.Key = Convert.FromBase64String(AesKey); // Encoding.UTF8.GetBytes(AesKey); 
            rijndaelCipher.IV = Convert.FromBase64String(AesIV);// Encoding.UTF8.GetBytes(AesIV); 
            rijndaelCipher.Mode = CipherMode.CBC;
            rijndaelCipher.Padding = PaddingMode.PKCS7;
            ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
            byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
            string result = Encoding.UTF8.GetString(plainText);

            return result;
        }
        catch (Exception)
        {
            return null;

        }
    }
    #endregion
}

2)微信授权用户反馈类 WxValidateUserResponse 和 微信用户信息类 WxResponseUserInfo

/// <summary>
/// 微信授权用户反馈类
/// </summary>
public class WxValidateUserResponse
{
    /// <summary>
    /// session_key
    /// </summary>
    public string session_key { get; set; }
    /// <summary>
    /// 单平台用户唯一ID
    /// </summary>
    public string openid { get; set; }
}

/// <summary>
/// 微信用户信息
/// </summary>
public class WxResponseUserInfo
{
    /// <summary>
    /// 单平台用户唯一ID
    /// </summary>
    public string openId { get; set; }
    /// <summary>
    /// 多平台用户公用唯一ID
    /// </summary>
    public string unionId { get; set; }

    /// <summary>
    /// 昵称
    /// </summary>
    public string nickName { get; set; }

    /// <summary>
    /// 性别
    /// </summary>
    public string gender { get; set; }

    /// <summary>
    /// 城市
    /// </summary>
    public string city { get; set; }

    /// <summary>
    /// 省份
    /// </summary>
    public string province { get; set; }

    /// <summary>
    /// 区
    /// </summary>
    public string country { get; set; }

    /// <summary>
    /// 头像Url
    /// </summary>
    public string avatarUrl { get; set; }

    public string sessionKey { get; set; }
}

第二步:创建 AccountController ,并且创建三个API方法 获取微信小程序授权信息  GetWxValidate 、注册入库 PostWxRegister 以及判断用户是否存在 GetExistsAccount

其中 请求https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2} 中用到的appid和secret 可以写在webconfig中

appid和secret需要登录微信公众平台  →  小程序 获取:

https://mp.weixin.qq.com/

/// <summary>
/// 账号API
/// </summary>
[RoutePrefix("Account")]
public class AccountController : BaseController
{
    #region +小程序模式注册登录
    /// <summary>
    /// 获取微信小程序授权信息
    /// </summary>
    /// <param name="code"></param>
    /// <returns></returns>
    [Route("GetWxValidate")]
    public BaseGetResponse<WxResponseUserInfo> Get(string code, string encryptedData, string iv)
    {
        StringBuilder urlStr = new StringBuilder();
        urlStr.AppendFormat(@"https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}"
                + "&grant_type=authorization_code",
                ConfigurationManager.AppSettings["XCXAppID"].ToString(),
                ConfigurationManager.AppSettings["XCXAppSecrect"].ToString(),
                code
            );
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlStr.ToString());
        request.Method = "GET";
        request.ContentType = "text/html;charset=UTF-8";

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        Stream myResponseStream = response.GetResponseStream();
        StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
        string retString = myStreamReader.ReadToEnd();
        myStreamReader.Close();
        myResponseStream.Close();
        WxValidateUserResponse vdModel = Newtonsoft.Json.JsonConvert.DeserializeObject<WxValidateUserResponse>(retString);

        if (vdModel != null)
        {
            GetUsersHelper.AesIV = iv;
            GetUsersHelper.AesKey = vdModel.session_key;
            string result = new GetUsersHelper().AESDecrypt(encryptedData);
            JObject _usrInfo = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(result);

            WxResponseUserInfo responseData = new WxResponseUserInfo
            {
                nickName = _usrInfo["nickName"].ToString(),
                gender = _usrInfo["gender"].ToString(),
                city = _usrInfo["city"].ToString(),
                province = _usrInfo["province"].ToString(),
                country = _usrInfo["country"].ToString(),
                avatarUrl = _usrInfo["avatarUrl"].ToString(),
                sessionKey= vdModel.session_key
        };
            responseData.openId = _usrInfo["openId"].ToString();
            try 
            {
                responseData.unionId = _usrInfo["unionId"].ToString();
            }
            catch (Exception)
            {
                responseData.unionId = "null";
            }
            return new BaseGetResponse<WxResponseUserInfo> { Code = ResultCode.NormalCode, Message = "微信认证成功", Data = responseData };
        }
        else
        {
            return new BaseGetResponse<WxResponseUserInfo> { Code = ResultCode.NotExistsValue, Message = "微信认证失败" };
        }
    }

    /// <summary>
    /// 小程序注册
    /// </summary>
    /// <param name="eneity"></param>
    /// <returns></returns>
    [Route("WXRegister")]
    public BaseUpdateModel PostWxRegister([FromBody]AccountDto eneity)
    {
        return new BTX.ShopAPI.Helper.OperationContext().AccountService.RegisterAccountAPI(eneity);
    }

    /// <summary>
    /// 账号重复验证
    /// </summary>
    /// <param name="identifier">账号</param>
    /// <returns></returns>
    [Route("ExistsAccount")]
    public BaseGetResponse<int> GetExistsAccount([FromUri]string identifier)
    {
      return operationContext.AccountAuthService.IsExsit(identifier);
    }
    #endregion
}

 

前端在请求的时候:

Step1:调用wx.login 和 wx.getUserInfo 获取反馈的code、加密数据及IV 请求 GetWxValidate

Step2:认证成功后返回微信用户的相关信息,通过返回信息中的openId 调用ExistsAccount判断该微信用户是否已经存在于本地库

Step3:如果不存在则插入本地库,否则返回本地库对应该微信用户的相关用户信息

 

第三步如何根据openId获取本地库信息见下一篇(其实下一篇已经是纯API开发的东西,就是数据库的查询返回数据的问题,如果有需要则查看,否则不需要了)

 

本系列其他教程见:

ASP.NET WEBAPI作服务端开发小程序实现微信授权用户登录实例(一)

ASP.NET WEBAPI作服务端开发小程序实现微信授权用户登录实例——后台API编写(二)

ASP.NET WEBAPI作服务端开发小程序实现微信授权用户登录实例——实现登录逻辑(三)

给我留言

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: