菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
261
0

uniapp(三)

原创
05/13 14:22
阅读数 77965

一,H5端和小程序的tabbar和顶部标题兼容性问题

 

 

 

1.1,此时我们的需求是鼠标滚动,让推荐推荐标签栏一下的页面滚动,而不是整个页面滚动

此时让html中滚动区域包裹scroll-view标签

<template>
        <view class="indexContainer">
            <view class="header">
                <image class="logo" src="/static/images/logo.png" mode=""></image>
                <view class="search">
                    <view class="iconfont icon-sousuo"></view>
                    <input class="searchInput" type="text" value="" placeholder-class="placeholder"  placeholder="搜索商品"/>
                </view>
                <button class="username">七月</button>
            </view>
            <scroll-view scroll-x="true" class="navScroll" enable-flex="true" v-if="indexData.kingKongModule" >
                <view class="navItem "  :class="currentIndex ===-1? 'active' :''"
                
                @click="changeNavIndex(-1)"
                >推荐</view>
                <view class="navItem" 
                :class="currentIndex===index ?'active':''"
                @click="changeNavIndex(index)"
                v-for="(item,index) in indexData.kingKongModule.kingKongList"
                :key="item.L1Id"
                >{{item.text}}</view>
            </scroll-view>
            <!-- 轮播图 -->
            <scroll-view scroll-y="true"  class="recommendScroll">
                <Recommend></Recommend>
            </scroll-view>
            
        </view>
</template>

 

此时h5页面和小程序计算高度发生了分歧

小程序中,要计算滚动区域的高度时,不需计算顶部标题的高度,以及tabbar栏的高度,此时滚动的区域高度为,height calc(100vh - 162upx)

在h5页面中,要计算滚动区域的高度时,需计算顶部标题的高度,以及tabbar栏的高度,此时滚动的区域高度为,height calc(100vh - 162upx-  88upx - 100upx)

此时他们高度不兼容,我们需要引入css变量,因为,

// --window-top->header占用的高度->H5端 44px->小程序端 0px

// --window-bottom->tabBar占用的高度->H5端 50px->小程序端 0px

 

 

stylus样式

        .recommendScroll
            // --window-top->header占用的高度->H5端 44px->小程序端 0px
            // --window-bottom->tabBar占用的高度->H5端 50px->小程序端 0px
            height calc(100vh - 162upx - var(--window-top) - var(--window-bottom))

 

二,登录个人中心模块,用户首次授权以及二次授权逻辑

2.1,在个人中心页面person.vue中,点击顶部登录区域,跳转到登录页面

 

 

<template>
    <div>
        <div class="header" @click="toLogin">
            <image class="userImg" :src="userinfo.avatarUrl? userinfo.avatarUrl : '../../static/images/personal/personal.png' " mode=""></image>
            <div class='userInfo'>
                <p>{{userinfo.nickName ? userinfo.nickName : '未登录'}}</p>
                <p>点击登录账号</p>
            </div>
        </div>
        
        <div class="content">
            <h2>我的资产</h2>
            <p class='line'></p>
            <div class="myAssetList">
                <div class='assetItem'>
                    <span>¥0</span>
                    <span>回馈金</span>
                </div>
                <div class='assetItem'>
                    <span>¥0</span>
                    <span>红包</span>
                </div>
                <div class='assetItem'>
                    <span>¥0</span>
                    <span>优惠券</span>
                </div>
                <div class='assetItem'>
                    <span>¥0</span>
                    <span>津贴</span>
                </div>
                <div class='assetItem'>
                    <span>¥0</span>
                    <span>礼品卡</span>
                </div>
            </div>
            <!-- 列表选项 -->
            <div class="personalList">
                <div class="navItem" v-for='(item, index) in personalList' :key='index'>
                    <i class='iconfont ' :class='item.icon'></i>
                    <p>{{item.name}}</p>
                </div>
            </div>
        </div>
    </div>
</template>

js

    methods: {
            toLogin(){
                // 如果用户授权登录了,不用再跳转
                if(this.userinfo) return
                uni.navigateTo({
                    url:"/pages/login/login"
                })
            }
        }

2.2,在登录页面,点击微信登录,获取授权行为,获取到用户信息,将用户信息保存到本地,以及路由授权成功后路由跳转到个人中新页

 

 

<template>
    <view class="loginContainer">
        <image class="logo" src="http://yanxuan.nosdn.127.net/39c5e4583753d4c3cb868a64c2c109ea.png" mode=""></image>
        <p class='text'>网易自营,精品生活家居品牌</p>
        <div class="loginMethods">
            <button class="login wechatLogin" open-type="getUserInfo" @getuserinfo="getuserinfo">
                微信登录
            </button>
            <button class="login emailLogin">
                邮箱登录
            </button>
        </div>
    </view>
</template>

js

    methods: {
            getUserInfo(res){
                let {rawData}=res.detail;
                console.log(res)
                if(rawData){
                    //如果授权成功,将用户信息存储至storage
                    uni.setStorage({
                        key:"userinfo",
                        data:rawData
                    })
                    //关闭所有页面,打开指定页面,指定页面会被重新挂载
                    uni.reLaunch({
                        url:"/pages/personal/personal?userinfo="+rawData
                    })
                }
                // console.log(res)
            }
        }

 

2.3, 在个人中心页获取到路由传递过来的query参数,并且对于二次登录授权,采取逻辑处理

 

 

        mounted(){
            //this身上拥有$mp属性,内部存储小程序原生options
            // console.log(this.$mp.query.userinfo)
            let {userinfo}=this.$mp.query;
            if(userinfo){
                //用于首次用户授权成功,login页面跳转回来之后触发
                this.userinfo=JSON.parse(userinfo)
            }else{
                //用于二次登录,用户授权已成功,直接获取用户之前的授权信息
                uni.getUserInfo({
                    success:(res)=>{
                        this.userinfo=res.userInfo
                    }
                })
            }
        },
    data(){
            return {
                userinfo:{},

2.4,如果用户授权登录成功后,不需要在跳转到登录页面了

    methods: {
            toLogin(){
                if(this.userinfo.nickName)return;
                uni.navigateTo({
                    url:"/pages/login/login"
                })
            }
        }

模板数据渲染

    <div class="header" @click="toLogin">
            <image class="userImg" :src="userinfo.avatarUrl? userinfo.avatarUrl : '../../static/images/personal/personal.png' " mode=""></image>
            <div class='userInfo'>
                <p>{{userinfo.nickName ? userinfo.nickName : '未登录'}}</p>
                <p>{{userinfo.nickName ? '微信用户' : '点击登录账号'}}</p>
            </div>
        </div>

个人中心顶部标题背景颜色修改,在page.json中配置

"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
        
        {
            "path": "pages/personal/personal",
            "style": {
                "navigationBarTitleText": "个人中心",
                "navigationBarBackgroundColor":"#EED7B5"
            }
        }

 

 

三,商品详情页发送请求获取数据

3.1,在商品列表页,点击商品,路由跳转到商品详情页,携带id参数,然后商品详情页,发送请求,获取数据

 

 

商品列表页

<template>
    <div class="listContainer">
        <div @click='toDetail(item.id)' class="listItem" v-for='(item, index) in shopList' :key='item.id'>
            <image :src="item.listPicUrl" mode=""></image>
            <p>{{item.name}}</p>
            <p style='color: red;font-weight: bold;'>$ {{item.retailPrice}}</p>
        </div>
    </div>
</template>

<script>
    export default {
        props: ['shopList'],
        methods: {
            toDetail(goodId){
                // wx.navigateTo({
                //     url: '/pages/detail/detail?shopItem=' + JSON.stringify(shopItem)
                // })
                wx.navigateTo({
                    url:"/pages/detail/detail?goodId="+goodId
                })
            }
        }
    }

商品详情页,发送请求,获取数据

        async mounted(){
            let {goodId}= this.$mp.query
            let goodDetail = await request('/getGoodDetail',{
                id:goodId
            })
            this.goodDetail =goodDetail
            
            
        },

 

    data() {
            return {
                goodDetail:{}
            }
        },

 

搭建服务端的路由配置

//json数据,
const goods = require('./datas/goods.json');
router.get('/getGoodDetail' ,function(ctx,next){
    let {id} = ctx.query
    // console.log(id)
    // 注意路由传参过来的数字是字符串格式
    let good=  goods.find((item,index)=> item.id === id*1)
    ctx.body = good
    
})

 

四,点击商品购物车按钮,将商品添加到购物车页面

 

 

 

4.1,新建cart.js的vuex,将数据保存在vuex中,cartList数据是购物车的数据,数据是太长,不显示

const state ={
    cartList:[

在商品详情组件中,映射mutations中的函数,将商品详情的数据传给store中的mutations中,然后修改state中的cartList数据

    <view class="btn addShopCart" @click="addShopItem">加入购物车</view>

 

    import {mapMutations} from 'vuex';
    async mounted(){
            let {goodId} = this.$mp.query;
            let good = await request('/getGoodDetail',{
                id:goodId
            });
            this.good=good
        },
        methods:{
            addShopItem(){
                //触发增加商品的mutation
                // this.$store.commit
                this.addShopItemMutation(this.good)
            },
            ...mapMutations(["addShopItemMutation"])
        }

 

在cart.js的vuex中mutations修改cartList

const mutations={
    addShopItemMutation(state,good){
        // console.log(good);
        //查询购物车列表中是否已存在准备新增的商品
        let shopItem=state.cartList.find(shopItem=>shopItem.id===good.id);
        if(shopItem){
            //如果购物车中已存在,只需要将他的数量+1
            shopItem.count++;
        }else{
            //如果购物车中不存在,给商品对象添加属性count,设置初始值为1,并添加至购物车列表中
             good.count=1;
           
        }
        // console.log('已添加至购物车')
    },

4.2,购物车组件的数据渲染,循环遍历

 

 

 

<view class="cartList">
            <view class="cartItem"  v-for="shopItem in cartList" :key="shopItem.id">
                <text class='iconfont icon-xuanzhong selected'></text>
                <view class="shopItem">
                    <image class="shopImg" :src="shopItem.listPicUrl" mode=""></image>
                    <view class="shopInfo">
                        <text>{{shopItem.name}}</text>
                        <text class="price">¥{{shopItem.retailPrice}}</text>
                    </view>
                </view>
                <!-- 控制数量 -->
                <view class="countCtrl">
                    <text class="add"> + </text>
                    <text class="count"> {{shopItem.count}}</text>
                    <text class="del"> - </text>
                </view>
            </view>
            
        </view>

 

此时有个bug,新增的商品,count属性不是响应式的,不会触发视图的更新,需要设置响应式属性

const mutations={
    addShopItemMutation(state,good){
        // console.log(good);
        //查询购物车列表中是否已存在准备新增的商品
        let shopItem=state.cartList.find(shopItem=>shopItem.id===good.id);
        if(shopItem){
            //如果购物车中已存在,只需要将他的数量+1
            shopItem.count++;
        }else{
            //如果购物车中不存在,给商品对象添加属性count,设置初始值为1,并添加至购物车列表中
            // good.count=1;
            // 给新增的商品对象,添加响应式属性count,初始值为1
            Vue.set(good,"count",1);
            Vue.set(good,"selected",true);
            state.cartList.push(good);
        }
        // console.log('已添加至购物车')
    },

 

五,购物车模块,修改商品数量逻辑

5.1,点击加减号,修改逻辑。对加减号进行标识,而且是对那个商品修改数量,将参数传到cart.js的vuex中,cartlist数组进行操作

<!-- 登陆之后的购物车 -->
            <view class="cartList">
                <view class="cartItem" v-for="(shopItem,index) in cartList" :key="shopItem.id">
                    <text class='iconfont icon-xuanzhong' @click="changeShopItemSelected(!shopItem.selected,index)" :class="shopItem.selected?'selected':''"></text>
                    <view class="shopItem">
                        <image class="shopImg" :src="shopItem.listPicUrl" mode=""></image>
                        <view class="shopInfo">
                            <text>{{shopItem.name}}</text>
                            <text class="price">¥{{shopItem.retailPrice}}</text>
                        </view>
                    </view>
                    <!-- 控制数量 -->
                    <view class="countCtrl">
                        <text class="add" @click="changeShopItemCount(true,index)"> + </text>
                        <text class="count"> {{shopItem.count}} </text>
                        <text class="del" @click="changeShopItemCount(false,index)"> - </text>
                    </view>
                </view>
                
            </view>

5.2, 映射cart.js中vuex中mutations,将参数传过去

import {mapState, mapMutations} from 'vuex'
methods:{
            changeShopItemCount(type,index){
                this.changeShopItemCountMutation({type,index})
            },
            
            ...mapMutations(['changeShopItemCountMutation'])

 

5.3,在cart.js的vuex中对cartlist数组操作,记住,传入到这里的参数要是个对象,解构下

changeShopItemCountMutation(state,{type,index}){
        /*需求:当用户点击+/-按钮时,去修改对应商品的数量
            拆解需求:
                1.绑定监听->监视用户点击操作
                2.区分点的到底是+还是-,+就是数量+1,-就是数量-1
                3.通过点击计数器找到对应的商品,并修改数量
                    1)+没有限制
                    2)-的情况,如果-1之后,不小于1,正常--
                            如果-1之后,小于1,直接从购物车中删除
        */
       // 通过传过来的下标,找到对应的商品
       let shopItem=state.cartList[index];
       if(type){
            //  点击的加号
           shopItem.count++;
       }else{
            //  点击的减号
           if(shopItem.count>1){
                shopItem.count--;
           }else{
                //  小于等于1,删除该商品
               state.cartList.splice(index,1);
           }
       }
        // console.log('changeShopItemCountMutation',state,type,index)
    },

5.4,在购物车页,如果是有数据,展示购物车数据,如果,没有数据,展示空的购物车页,需要用到v-if,v-else

 

 

block标签只是展示而且,没有实际意义

<template>
    <view class="cartContainer">
        <view class="title">购物车</view>
        
        <!-- 未登录时候的购物车 -->
        <block v-if="cartList.length===0">
            <view class="header">
                <text>30天无忧退货</text>
                <text>48小时快速退货</text>
                <text>满99元免邮费</text>
            </view>
            <view class="contentContainer">
                <image class="cartImg" src="http://yanxuan-static.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/noCart-d6193bd6e4.png?imageView&type=webp" mode=""></image>
                
                <view class="addMore">去添加点什么吧</view>
            </view>
            
        </block>
        
        <block v-else>
            <!-- 登陆之后的购物车 -->
            <view class="cartList">
                <view class="cartItem"  v-for="(shopItem,index) in cartList" :key="shopItem.id">
                    <text class='iconfont icon-xuanzhong selected'></text>
                    <view class="shopItem">
                        <image class="shopImg" :src="shopItem.listPicUrl" mode=""></image>
                        <view class="shopInfo">
                            <text>{{shopItem.name}}</text>
                            <text class="price">¥{{shopItem.retailPrice}}</text>
                        </view>
                    </view>
                    <!-- 控制数量 -->
                    <view class="countCtrl">
                        <text class="add"   @click="changeShopItemCount(true,index)"> + </text>
                        <text class="count"> {{shopItem.count}}</text>
                        <text class="del"   @click="changeShopItemCount(false,index)"> - </text>
                    </view>
                </view>
                
            </view>
            <!-- 底部下单 -->
            <view class="cartFooter">
                <text class='iconfont icon-xuanzhong selected'></text>
                <text class="allSelected">已选 3</text>
                <view class="right">
                    <text class="totalPrice">合计: ¥1000</text>
                    <text class="preOrder">下单</text>
                </view>
            </view>
                
        </block>
        
    </view>
</template>

 

六,购物车模块,商品选中状态逻辑

6.1,selected类是选中的状态,点击选中框,切换状态,将参数传给cart.js中的vuex,cartlist数据逻辑整理

    <view class="cartItem"  v-for="(shopItem,index) in cartList" :key="shopItem.id">
                    <text class='iconfont icon-xuanzhong '   @click="changeShopItemSelected(!shopItem.selected,index)" :class="shopItem.selected?'selected':''"></text>
                    <view class="shopItem">
                        <image class="shopImg" :src="shopItem.listPicUrl" mode=""></image>
                        <view class="shopInfo">
                            <text>{{shopItem.name}}</text>
                            <text class="price">¥{{shopItem.retailPrice}}</text>
                        </view>
                    </view>

js

    changeShopItemSelected(selected,index){
                this.changeShopItemSelectedMutation({selected,index});
            },
            
            ...mapMutations(['changeShopItemCountMutation','changeShopItemSelectedMutation'])

在cart.js的vuex,此时selected的属性也不是响应式的,需要在添加购物车商品的时候一起添加

changeShopItemSelectedMutation(state,{selected,index}){
                /*
                    单次点击需求:当用户点击选中按钮,将对应商品的选中状态进行修改
                    全选按钮需求:
                */
               let shopItem = state.cartList[index];
               shopItem.selected=selected;
               // console.log(selected,index)
            },

 

    addShopItemMutation(state,good){
        // console.log(good);
        //查询购物车列表中是否已存在准备新增的商品
        let shopItem=state.cartList.find(shopItem=>shopItem.id===good.id);
        if(shopItem){
            //如果购物车中已存在,只需要将他的数量+1
            shopItem.count++;
        }else{
            //如果购物车中不存在,给商品对象添加属性count,设置初始值为1,并添加至购物车列表中
            // good.count=1;
            // 给新增的商品对象,添加响应式属性count,初始值为1
            Vue.set(good,"count",1);
            Vue.set(good,"selected",true);
            state.cartList.push(good);
        }
        // console.log('已添加至购物车')
    },

 

七,全选按钮状态处理逻辑

7.1,当单选都选中,全选按钮才选中

在cart.js中的getters中计算全选按钮状态

const getters={
    isSelectedAll(state){
        /*
            需求:
                1)当购物车中没有商品,全选按钮应该是未选中状态
                2)当购物车中所有商品都是选中状态,全选按钮应该也是选中状态->true
                3)当购物车中有部分商品未选中,全选按钮应该是未选中状态->false
                4)返回值类型:布尔值
                5)书写位置:getter
                
                every->所有的元素都满足条件,返回值就是true,只要有一个不满足,结果就是false
                some->只要有一个元素满足条件,返回值就是true,反之,则是false
        */
       let {cartList} =state;
       if(cartList.length===0) return false;
       let result = cartList.every(item=>item.selected);
       return result;
       // console.log(result)
    }
}

在购物页映射getters

import {mapState,mapMutations,mapGetters} from 'vuex'
computed:{
            ...mapState({
                cartList:state=>state.cart.cartList
            }),
            ...mapGetters(["isSelectedAll"])
        },
<!-- 底部下单 -->
        <view class="cartFooter">
            <text class='iconfont icon-xuanzhong '  :class="isSelectedAll?'selected':''"></text>
            <text class="allSelected">已选 3</text>
            <view class="right">
                <text class="totalPrice">合计: ¥1000</text>
                <text class="preOrder">下单</text>
            </view>
        </view>

 

八,点击全选按钮,单选按钮全部勾选上

<view class="cartFooter">
            <text class='iconfont icon-xuanzhong '  @click="changeSelectedAll(!isSelectedAll)" :class="isSelectedAll?'selected':''"></text>
            <text class="allSelected">已选 3</text>
            <view class="right">
                <text class="totalPrice">合计: ¥1000</text>
                <text class="preOrder">下单</text>
            </view>
        </view>

js,将全选状态穿到cart.js的vuex中,

changeSelectedAll(selected){
                this.changeSelectedAllMutation(selected);
            },
            
            ...mapMutations(['changeShopItemCountMutation','changeShopItemSelectedMutation', 'changeSelectedAllMutation'])

cart.js中vuex中处理状态

changeSelectedAllMutation(state,selected){
                /*
                    需求:当用户点击全选按钮时,改变所有商品选中状态(根据当前全选按钮的情况取反)
                    拆分需求:
                        1)当用户点击->监听
                        2)获取到当前全选按钮的状态,并且取反(得到状态a)
                        3)将所有商品的状态设置为a
                */
               state.cartList.forEach(item=>item.selected=selected)
               // console.log(result)
            }    

 

九,获取用户唯一标识openId

购物车模块(重点:获取用户唯一标识openId)
  1)无论是点击open-type为getUserInfo的button组件,还是使用wx.getUserInfo方法获取到的用户信息中,都没有用户的唯一标识
  2)想要获取用户的唯一标识需要用到wx.login接口并配合服务器进行
    流程:
        1.客户端通过wx.login()获取到用户的临时登录凭证code
        2.将code发送给我们自己的服务器
        3.服务器将code+appid+appsecret发送给微信官方服务器
        4.微信官方服务器返回session_key以及用户唯一标识openId
        5.在服务器端对openId进行加密,最后返回给客户端
        6.客户端接收到加密之后的openId,并存储到Storage中

 

将临时登录凭证吗code, appid,AppSecret(小程序密钥)收集起来,在node服务端发送请求,通过微信自己的接口,返回唯一凭证openId

 

 

 

调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key。
GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

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

注意:

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

9.1,我们在app.vue中的onShow函数中,获取登录临时凭证,并且发送请求,将code传递过去

onShow: function() {
            wx.login({
                // 解构
                async success({code}){
                    // console.log(code)
                    let openId = await request('/getOpenId',{code});
                    uni.setStorage({
                        key:"openId",
                        data:openId
                    })
                }
            })
            
        },
     

9.2,在node服务器中临时登录凭证吗code, appid,AppSecret(小程序密钥)收集起来,发送请求,通过微信小程序自己的接口,获取到唯一标识openId

注;fly.js,请求库  npm i flyio

一个支持所有JavaScript运行环境的基于Promise的、支持请求转发、强大的http请求库。可以让您在多个端上尽可能大限度的实现代码复用。

例子

//query参数通过对象传递
fly.get('/user', {
      id: 133
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

引入fly

const Fly=require("flyio/src/node")
const fly=new Fly;

 

// 用于获取用户唯一标识OpenId
router.get('/getOpenId',async (ctx,next)=>{
    // console.log(ctx.query.code)
    let {code} = ctx.query;
    let appid="wx7ab0b2d5ff1862";
    // AppSecret(小程序密钥)
    let appSecret="35d565a8f9984aa0d9816e9aaf509de";
    let data;
    // 微信小程序提供的接口
    let url= `https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${appSecret}&js_code=${code}&grant_type=authorization_code`
    // 利用fly.js库发送请求
    let result = await fly.get(url)
    // 转换成字符串
    data=JSON.parse(result.data);
    // 获取openid,session_key
    let {openid,session_key} =data;
    
    ctx.body=openid;
})

 

9.3,在app.vue中的onShow函数中,获取到登录唯一凭证openid,然后保存在本地,并且在请求头上携带
onShow: function() {
            // console.log('App Show')
            wx.login({
                // 解构
                async success({code}){
                    // console.log(code)
                    let openId = await request('/getOpenId',{code});
                    uni.setStorage({
                        key:"openId",
                        data:openId
                    })
                }
            })
        },
export default function(url,data={},method="GET"){
    // console.log(uni.getSystemInfoSync());
    // console.log(process.env.NODE_ENV)
    return new Promise((resolve,reject)=>{
        uni.request({
            url:baseURL+url,
            data,
            method,
            header:{
                "token":uni.getStorageSync('openId')
            },
            success(res){
                resolve(res.data)
                // console.log(res)
            },
            fail(error){
                console.log(error)
                // reject(error)
                resolve(false)
            }
        })
    })
}

 

十,在node中对唯一标识openId进行加密

购物车模块(对openId进行加密操作)
  1)下载jwt加密包,npm install jsonwebtoken
  2)使用方法:
    加密:使用jwt.sign(需要加密的数据,提高解密难度的数据),可以获得加密之后的token
    解密:使用jwt.verify(token,提高解密难度的数据),可以获得加密前的openId
  3)将服务器的openId加密成token,返回给小程序客户端
  4)小程序客户端获得token之后,将token存储至Storage中

 

jwt,github上搜索jsonwebtoken,数据加密 npm install jsonwebtoken

引入

const jwt = require('jsonwebtoken');
// 用于获取用户唯一标识OpenId
router.get('/getOpenId',async (ctx,next)=>{
    // console.log(ctx.query.code)
    let {code} = ctx.query;
    let appid="wx7ab0b2d5ff1862";
    // AppSecret(小程序密钥)
    let appSecret="35d565a8f9984aa0d9816e9aaf509de";
    let data;
    // 微信小程序提供的接口
    let url= `https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${appSecret}&js_code=${code}&grant_type=authorization_code`
    // 利用fly.js库发送请求
    let result = await fly.get(url)
    // 转换成字符串
    data=JSON.parse(result.data);
    // 获取openid,session_key
    let {openid,session_key} =data;
    // console.log(result)
    // 加密 jwt.sign(需要加密的数据,salt(盐))
    //    盐->提高解密的难度(暴利破解的难度)
    // console.log(openid)
    let salt = "aotemannihao";
    let token = jwt.sign(openid,salt);
    // console.log(token)
    //尝试解密token
    //    解密        jwt.verify(token,salt(盐))
    let newOpenId = jwt.verify(token,salt);
    console.log(openid,newOpenId)
    ctx.body=token;
})

 

 

发表评论

0/200
261 点赞
0 评论
收藏