zoukankan      html  css  js  c++  java
  • uniapp(三)

    一,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;
    })
  • 相关阅读:
    不用if/else swich for while实现累加
    1.java数据结构
    青蛙跳台阶问题
    next与nextLine
    9.遗传算法
    Docker镜像管理
    Docker镜像管理
    CentOS 6.7安装Docker
    CentOS 6.7安装Docker
    数字三角形_递归_递推(动态规划)
  • 原文地址:https://www.cnblogs.com/fsg6/p/13704110.html
Copyright © 2011-2022 走看看