小程序登录流程解析

写在前面

对于一个应用,基本需要登录后才能使用的功能
我们需要有一个登录流程,拿小程序来说吧:
小程序登录流程解析_第1张图片

小程序登录: 登录
wx.login - > 在request请求, 拿到openid


示例:

import { Sid, AppId, OpenId, RegisterCode } from './storage'
import { promisify } from './promisify'
import Toast from '../static/vant-weapp/toast/toast';
import Dialog from '../static/vant-weapp/dialog/dialog';
import env from './../env';

const apiPrefix = `${env.baseUrl}/api/`;

const app = getApp()

const wxLogin = promisify(wx.login)
const wxRequest = promisify(wx.request)


function getAppId() {
    let appId = AppId.get()
    if (!appId) {
        appId = wx.getAccountInfoSync().miniProgram.appId;
        AppId.set(appId)
    }
    return appId;
}

//这里应该是session状态码
const getLoginCode = async function() {
    let wxLoginRes = await wxLogin()
    console.log("wxLogin() --- success", wxLoginRes);
    let saveSessionRes = await wxRequest({
        method: "POST",
        url: apiPrefix + "user/saveSession",
        data: {
            appId: getAppId(),
            code: wxLoginRes.code
        }
    })
    if (saveSessionRes.data.code !== 0) {
        // wx.showToast({ title: saveSessionRes.data.msg, icon: "none" });
        return Promise.reject(saveSessionRes.data.msg)
    }
    OpenId.set(saveSessionRes.data.data.openId) //openid
    return saveSessionRes.data.data.openId
}
//得到id
const getOpenId = async() => { //仅仅获取 openId
    let openId = OpenId.get()
    if (!openId) openId = await getLoginCode()
    return openId;
}
// 登录
const login = async() => {
    const openId = await getOpenId()
    console.log("我要登录了!!!注册码是:", RegisterCode.get());
    const loginRes = await wxRequest({
        method: "POST",
        url: apiPrefix + "user/login",
        data: { appId: getAppId(), openId, inviteCode: RegisterCode.get() }
    })
    console.log("登录返回的数据:", loginRes.data);
    if (loginRes.data.code !== 0) {
        if (loginRes.data.code === -3) {
            await Dialog.confirm({ message: '此页面需要登录,是否允许登录?' })
            wx.navigateTo({ url: "/pages/gzhLogin/index" });
        }
        return Promise.reject(loginRes)
    }
    Sid.set(loginRes.data.data)
    return loginRes
}

// 登录状态/// 可否将request做近一步的封装, 方便操作(像axios一样)
const getRegStatus = async() => {
    const openId = await getOpenId()
    console.log("我要登录了!!!注册码是:", RegisterCode.get());
    const res = await wxRequest({
        method: "POST",
        url: apiPrefix + "user/login",
        data: { appId: getAppId(), openId, inviteCode: RegisterCode.get() }
    })
    console.log("登录返回的数据:", res.data);
    return res
}

module.exports = { login, getOpenId, getLoginCode, getRegStatus }

在进行数据请求的封装

import { Sid, AppId } from './storage'
import loginLib from './login'
import { promisify } from './promisify'
import env from './../env';

const baseUrl = env.baseUrl + "/";
const apiPrefix = `${baseUrl}api/`;

const wxRequest = promisify(wx.request)

  
//appid??  (不知道是个什么东西)
function getAppId() {
    let appId = AppId.get()
    if (!appId) {
        appId = wx.getAccountInfoSync().miniProgram.appId;
        AppId.set(appId)
    }
    return appId;
}

export function $post(options) {
    if (typeof options !== 'object') {
        return Promise.reject('请求传参应为 object 类型,但实际传了 ' + (typeof options) + ' 类型')
    }
    let hasRetried = false
    // 先执行登录操作,再请求
    function doRequestWithLogin() {
        console.log("doRequestWithLogin");
        return loginLib.login().then(doRequest).catch(err => {
            return Promise.reject(err)
        })
    }

    // 实际进行请求
    async function doRequest() {
        let header = {}
        if (options.noLogin) {
            header = { "content-type": "application/json" }
        } else {
            header = { sid: Sid.get() }
        }
        let urlPrefix = apiPrefix;
        if(options.useApiPrefix === false) {//是否使用 api 路径前缀,默认都是使用
            urlPrefix = baseUrl;
        }
        const openId = await loginLib.getOpenId()
        return wxRequest({
            url: urlPrefix + options.url,
            method: "POST",
            header,
            data: { appId: getAppId(), openId, ...options.data },
            dataType: "json",
        }).then(response => {
            const ret = response.data
            if (ret && ret.code === -2) {
                Sid.clear()

                if (!hasRetried) {
                    hasRetried = true
                    return doRequestWithLogin()
                }
                return Promise.reject(ret)
            } else if (ret.code !== 0) {
                // Toast(ret.msg)
                if(!options.hideToast){
                    wx.showToast({
                        title: ret.msg,
                        icon: 'none',
                        duration: 2000
                    })
                }
                return Promise.reject(ret.msg)
            }
            return Promise.resolve(ret)
        }).catch(error => {
            return Promise.reject(error)
        })
    }

    // 开始进行请求
    return options.login ? doRequestWithLogin() : doRequest()
}

使用then接收或者,结果
示例请求:
let res = await $post({ url: "shop/getWxaSceneInfo", data: { key }, noLogin: true })

你可能感兴趣的:(小程序,#,JS封装,JavaScript)