Code前端首页关于Code前端联系我们

简单小程序开发:关于登录的一些事

terry 2年前 (2023-09-22) 阅读数 74 #移动小程序

整理登录流程

这里有一些需要注意的地方:

  1. 注意使用es6语法。 es6语法在小程序中会更有用。最关键的一点是,小程序的大部分API都是异步的。要使旧方式异步,必须使用回调,而回调很容易搞乱代码逻辑,因此必须使用 Promise 并封装接口。 。
  2. 注重效率。例如,在获取代码时,您应该注意在第一次之后以及第一次尝试以外的情况下保存它。然后你就可以直接从缓存中获取它,这已经不是第一次了。这样的地方有好几个,需要注意一下。
  3. 首先理清业务逻辑、登录逻辑、产品体验逻辑,别忘了先画流程图,因为小程序的逻辑比一般逻辑复杂一点。是的,这很令人困惑。所以你需要注意平滑它。
  4. 注意接口的调用顺序,这和流程图有很大关系。对照官方文档,一步步处理。由于使用了异步,因此您必须弄清楚异步 Promise 解析和拒绝,这对于多个 Promise 来说会更加困难。 ,但是有一些技术可以避免这种情况,其细节将在下面讨论。
  5. 一定要注意解密签名的过程。即使它发生在服务器端,你也需要了解如何控制它,因为你还需要分析服务器端对等点以及如何与小程序一起处理它。
  6. 需要理解每个关键变量element、code、session_key、3rd_session、openid、unioinid的含义才能理解文档的整体思路。
  7. 需要注意openId和unioinId的使用

微信小程序登录开发图

引用银姐的图,因为这张图比官方的清晰一点。

小程序简单开发:关于登录的一些事

代码逻辑流程图

我引用的是银杰的图,因为这个图比官方的更清晰一点。

小程序简单开发:关于登录的一些事

腾讯weapp-session代码流程图

腾讯weapp-session图引用

小程序简单开发:关于登录的一些事

他们还提供了更详细的分步代码处理流程,可以和自己的程序进行对比。

  1. 客户端(微信小程序)发起请求 请求
  2. requirement-application-session-client 请求❙❙第一个请求
  3. 第一个请求
  4. 第一个请求 并且 () 接口获取代码rawData和签名
  5. 请求代码、 rawData 和 签名
  6. 保存代码以供下次调用
  7. 不是第一个请求
  8. 服务器收到请求列表 代码原始数据签名字段
    • 如果‼为空,跳转到步骤❙4
    • 代码不为空且 rawData
    不为空,签名需要验证
    • 使用、‼‼app〼app_secret
    请求微信接口获取session_keyopenid 如果接口失败,答案是 ERR_SESSION_KEY_EXICH 签名 rawData a session_key 计算签名 signature2
  9. 比较签名aaa a a a ❙ 是一致的签名2
  10. rawData 是wxUserInfo
    • openid 写入wxUserInfo
    • (代码, wxUserInfo)❙ 缓存wxUserInfo 存储在请求中。 $wxUserInfo inside
    • 跳转到步骤4
  11. 签名不一致,响应为ERR_UNTRUSTED_RAW_DATA❙不为空,但rawData 为空,根据从Redis中查询
    • 缓存中的用户信息,找到用户信息,存储到字段中。 未搜索到用户信息(可能已过期),响应err_session_expired
  12. 请求已由业务处理,可以使用请求。 $WXUserinfo获取用户信息(要求。$wx UserInfo可以为空,需要自己处理业务)

流程图汇总

  1. 代码为微信用户登录信息。当您打开迷你登录程序时,您将获得仅属于微信用户的登录信息。注:是的,该登录仅微信小程序使用。
  2. session_key是微信用户在小程序中的登录状态信息。相当于微信向该用户发出的登录会话。官方网址是
    • 它有一个过期时间 {"session_key":"...","expires_in":7200,"openid":"..."} 需要定期检查。
  3. openId,唯一用户标识符
  4. unioinId。如果开发者拥有多个移动应用、网页应用、公众号(包括小程序),可以使用unionid来区分用户的唯一性,因为如果是移动应用、网页应用、公众号(含小程序)在微信开放平台同一账号下,用户unionid是唯一的。也就是说,对于同一个用户,在同一个微信开放平台上的不同应用,unionid是相同的。
  5. 一般来说,openId是一个微信用户的唯一标识,但由于微信产品较多,多个微信产品会使用不同的openId,如果我们是做业务方式的话,我们需要购买方式来使用,所以建议统一使用unioinid,因为一般来说一般商家都会有公众号和小程序一起使用。
  6. 3rd_session一般是指我们自己公司的服务器session。一般来说,可以和原来的业务会话一起使用,但是这个会话过期时间键❙❙❙❙❙❙❙_session❙❙小程序。这可以限制重复创建 会话 。另外,一般来说,我们自己公司服务器的管理session 管理将使用redis等数据库进行管理。我们先笼统地理解一下,因为在其他文章中也会提到。
  7. 为什么要使用 2 个会话session_key'3rd_session'3rd_session) session_key为微信登录状态,为我们交易系统的登录状态,双方都有一个登录状态,所以需要将两个登录状态合并为一个session,合并为3rd_session并保存然后每次我们需要使用的时候,小程序都会带着这个3rd_session来访问我们的交易系统,通过处理我们可以返回unioinid以及其他我们需要的session每次都会获取一个新的 session_key(因为微信对代码的使用有限制,所以需要使用替换 session_key )。一般使用 3rd_session来管理微信的登录状态小程序

关于解密

官方文档:数据验证是为了提高数据安全性,我们需要获取用户的unioinid,需要调用接口获取,但正常情况下获取到的数据是

{
  "nickName": "Band",
  "gender": 1,
  "language": "zh_CN",
  "city": "Guangzhou",
  "province": "Guangdong",
  "country": "CN",
  "avatarUrl": ""
}

如果需要业务访问,没有unioinid就没有意义,所以需要按照官方的方法解密。解密后的数据包含unioinid

{
    "openId": "OPENID",
    "nickName": "NICKNAME",
    "gender": GENDER,
    "city": "CITY",
    "province": "PROVINCE",
    "country": "COUNTRY",
    "avatarUrl": "AVATARURL",
    "unionId": "UNIONID",
    "watermark":
    {
        "appid":"APPID",
    "timestamp":TIMESTAMP
    }
}

封装的网络接口

因为小程序的所有网络请求都是异步的,异步会导致很多重回调问题,所以改为promise。使用 Promise 时,必须特别注意决策处理和返回。

例如:

const httpRequest = (api, data) => {
    let serverHost = env.serverHost;

    return new Promise(function (resolve, reject) {
        //发起网络请求
        ({
            url: serverHost + api,
            data: data,
            header: {
                'content-type': 'application/x-www-form-urlencoded'
            },
            success: function (res) {
                if (.errno === 0) {
                    // 需要下一步处理的就用 resolve 返回
                    resolve();
                }
                else {
                    ("http fail:api:" + api + "res:" + (res));
                    // 需要跳出循环处理的就用 reject
                    reject();
                }
            }, fail: function (res) {
                ("http fail:api:" + api + "res:" + (res));
                // 需要跳出循环处理的就用 reject
                reject(res);
            }
        })
    })
};

在多个 Promise 的情况下,你需要注意两件事:

  1. 你必须返回一个可用的 Promise 实例
  2. 即使出现异步和分支,也尽量关注统一流程中的处理采用统一拒绝跳转,而不是单独异步弹出,使得流程更加统一,更易于管理。
getCode() // 获取 wx code
            .then(code => {
                wxCode = code;
                // 这里getSetting是一个返回的 promise实例,如上面的那个
                return getSetting(); // 获取 setting
            })
            .then(res => {
                if ([""]) {
                    // 这里getUserInfo是一个返回的 promise实例
                    return getUserInfo(self);
                } else {
                    ("first auth none:" + (res));
                    // 类似
                    return util.showModal("亲,还没有授权!")
                        .then(res => {
                            return getAuth("userInfo");
                        }).then(res => {
                            // 检查授权是否正常
                            return getSetting();
                        })
                        .then(res => {
                            if ([""]) {
                                return getUserInfo(self);
                            } else {
                                return Promise.reject(res);
                            }
                        });
                }
            })
            .catch(err=>{
                ("err"+err);    
            })

关注友情提示

微信小程序的“授权失败”场景需要优雅处理,以提高用户体验。看一下这里: ​​可以看到一点如何生效的:

将判断放入 处理后,如果判断没有权限,会弹出一个弹窗:

({
    success: function success(res) {
        ();
        var authSetting = ;
        if (authSetting[''] === false) {
                ({
                    title: '用户未授权',
                    content: '如需XXXXXXX。',
                    showCancel: false,
                    success: function (res) {
                        if () {
                            ('用户点击确定')
                            ({
                                success: function success(res) {
                                }
                            });
                        }
                    }
                })
        }
    }
});

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门