zoukankan      html  css  js  c++  java
  • WebAPI 微信小程序的授权登录以及实现

    这个星期最开始 ,老大扔了2个任务过来,这个是其中之一。下面直接说步骤:

    1.  查阅微信开发文档

      https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html

    我将两个重要的地方列出来

    a  登录流程时序图,及说明

    登录流程时序

    说明:

    1. 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
    2. 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key

    之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

    注意:

    1. 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥
    2. 临时登录凭证 code 只能使用一次

    b. auth.code2Session 的文档说明

    auth.code2Session

    本接口应在服务器端调用,详细说明参见服务端API

    登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。更多使用方法详见 小程序登录

    请求地址

    GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
    

    请求参数

    属性类型默认值必填说明
    appid string   小程序 appId
    secret string   小程序 appSecret
    js_code string   登录时获取的 code
    grant_type string   授权类型,此处只需填写 authorization_code

    返回值

    Object

    返回的 JSON 数据包

    属性类型说明
    openid string 用户唯一标识
    session_key string 会话密钥
    unionid string 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见UnionID 机制说明
    errcode number 错误码
    errmsg string 错误信息

    errcode 的合法值

    说明最低版本
    -1 系统繁忙,此时请开发者稍候再试  
    0 请求成功  
    40029 code 无效  
    45011 频率限制,每个用户每分钟100次

    2.  WebAPI 实现代码:主要包含三部分

    第一部分:建立处理传入参数和返回参数的Model

    微信小程序传入参数Model

        public class WeXinLoginInModel
        {
            /// <summary>
            /// 小程序appid
            /// </summary>
            public string AppId { get; set; }
            /// <summary>
            /// 小程序appSecret
            /// </summary>
            public string AppSecret { get; set; }
            /// <summary>
            /// 小程序code
            /// </summary>
            public string Code { get; set; }     
        }

    小程序所需返回参数Model

       public class WeXinLoginResultModel
        {
            /// <summary>
            /// 用户唯一标识
            /// </summary>
            public string OpenId { get; set; }
            /// <summary>
            /// 会话密钥
            /// </summary>
            public string Session_Key { get; set; }
            /// <summary>
            /// 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见UnionID 机制说明。
            /// </summary>
            public string Unionid { get; set; }
            /// <summary>
            /// 错误码
            /// </summary>
            public int ErrCode { get; set; }
            /// <summary>
            /// 错误信息
            /// </summary>
            public string ErrMsg { get; set; }
            /// <summary>
            /// Redis里面OpenId值所对应的键OpenIdKey
            /// </summary>
            public string OpenIdKey { get; set; }
            /// <summary>
            /// Redis里面Session_Key值所对应的键SessionKey
            /// </summary>
            public string SessionKey { get; set; }
        }

    第二部分:WebAPI里面写方法,

    调用 auth.code2Session里面的请求地址,然后将返回结果中的OpenId、Session_Key以键值对的形式存储起来,而且将键名称相关的信息返回给微信端。

     [HttpGet("~/api/WeiXinLogin", Name = "WeiXinLogin")]
            public async Task<IActionResult> WeiXinLogin(string js_code)
            {      
             WeXinLoginInModel weixin = new WeXinLoginInModel();
               weixin.AppId = "wx30a387595dafb442";    //固定值,请参照小程序参数说明
               weixin.AppSecret = "4e24cab02422082b11a406595dacee76";///固定值,请参照小程序参数说明
               weixin.Code = js_code; //不固定
    
                string param = $"?appid={weixin.AppId}&secret={weixin.AppSecret}&js_code={weixin.Code}&grant_type=authorization_code";
    ;            string url = "https://api.weixin.qq.com/sns/jscode2session"+param;
          
                var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };
                using (var http = new HttpClient(handler))
                {
                    //await异步等待回应
                    var response = await http.GetAsync(url);
                    //确保HTTP成功状态值
                    response.EnsureSuccessStatusCode();
                   var a=  response.StatusCode;
    
                    //await异步读取最后的JSON(注意此时gzip已经被自动解压缩了,因为上面的AutomaticDecompression = DecompressionMethods.GZip)
                    string responseContent= await response.Content.ReadAsStringAsync();
                    var resultModel= JsonConvert.DeserializeObject<WeXinLoginResultModel>(responseContent);
                    if(!string.IsNullOrEmpty(resultModel.OpenId) && !string.IsNullOrEmpty(resultModel.Session_Key))
                    {
                        //将openid,session_key存入到Redis缓存中;              
                        string openIdKey = "openIdKey_" + Guid.NewGuid().ToString();
                        string sessionKey = "sessionKey_" + Guid.NewGuid().ToString();
                        _redisCacheManager.Set(openIdKey, resultModel.OpenId, TimeSpan.FromDays(1));
                        _redisCacheManager.Set(sessionKey, resultModel.Session_Key, TimeSpan.FromDays(1));
                        resultModel.OpenIdKey = openIdKey;
                        resultModel.SessionKey = sessionKey;
                    }
                  
                    //返回结果
                    return Ok(resultModel);             
                }         
            }

    第三部分:微信端将键名称存入storage值,

    方便下次发起业务请求时带上这个Storage值,去后端验证OpenId、Session_Key是否有值,若有值,返回业务数据。

         公司老大说他用Token,    后面我没做了,过程省略。现提供后续思路如下:Storage值里面取出openIdKey、SessionKey——Redis 缓存里面根据openIdKey、SessionKey 取出openId、Session_Key——如果openId、Session_Key里面有值,说明该用户前面登录过,有权进行接下来的业务操作

     

  • 相关阅读:
    BZOJ3105:[CQOI2013]新Nim游戏(线性基,贪心)
    BZOJ5102:[POI2018]Prawnicy(贪心,堆)
    BZOJ3533:[SDOI2014]向量集(线段树,三分,凸包)
    BZOJ3569:DZY Loves Chinese II(线性基)
    BZOJ3534:[SDOI2014]重建(矩阵树定理)
    【BZOJ 1202】 [HNOI2005]狡猾的商人
    【BZOJ 1003】 [ZJOI2006]物流运输trans
    【BZOJ 2321】 [BeiJing2011集训]星器
    【BZOJ 1010】 [HNOI2008]玩具装箱toy
    【BZOJ 2730】 [HNOI2012]矿场搭建
  • 原文地址:https://www.cnblogs.com/for-easy-fast/p/12134659.html
Copyright © 2011-2022 走看看