uniapp实现多端开发, PHP写api接口的一些注意事项与安全策略_优品建站

uniapp实现多端开发, PHP写api接口的一些注意事项与安全策略

  多端开发,听名字就感觉不一样,一套代码,多端使用。适用于各个平台。是不是很高大上。
  市面上很多关于多端开发的框架,比较常用,流行的框架 uni-app,Chameleon(变色龙),taro这些,都可以支持多端,一套代码,8个平台支持
  常见平台分别是H5页面,安卓,微信小程序,百度小程序,支付宝小程序,头条小程序这几个平台
  下面以一个登陆的例子给大家介绍一下
一、创建项目、后端环境介绍
创建项目
打开HBuilderX -> 新建 uniapp 项目;
创建页面
|_ index.vue 入口页面
|_ write.vue 文章撰写页面
|_ my.vue 账户中心页面
后端使用php+mysql
完善底部导航栏
下载图标, 图标地址 :
https://pan.baidu.com/s/1iaWd6l_-cIJ3RNUsqNqFNQ
将图标部署至 /static 目录;
修改 page.json
  "tabBar" : {
        "color" : "#707070",
        "selectedColor" : "#DE533A",
        "list" : [
            {
                "pagePath" : "pages/index/index",
                "text" : "文章",
                "iconPath" : "static/nav1.png",
                "selectedIconPath" : "static/nav1-a.png"
            },
            {
                "pagePath" : "pages/write/write",
                "text" : "写作",
                "iconPath" : "static/nav2.png",
                "selectedIconPath" : "static/nav2-a.png"
            },
            {
                "pagePath" : "pages/my/my",
                "text" : "我的",
                "iconPath" : "static/nav3.png",
                "selectedIconPath" : "static/nav3-a.png"
            }
        ]
    }
4.修改项目名称"globalStyle" : {
    "navigationBarTextStyle" : "black",
    "navigationBarTitleText" : "悦读",
    "navigationBarBackgroundColor" : "#F8F8F8",
    "backgroundColor" : "#F8F8F8"
}
5.加载 colorUI 框架
https://github.com/weilanwl/ColorUI
二、封装全局登录检查函数并部署
1、在 main.js 中封装全局登录函数Vue.prototype.checkLogin = function(backpage, backtype){
    var SUID  = uni.getStorageSync('SUID');
    var SRAND = uni.getStorageSync('SRAND');
    var SNAME = uni.getStorageSync('SNAME');
    var SFACE = uni.getStorageSync('SFACE');
    if(SUID == '' || SRAND == '' || SFACE == ''){
        uni.redirectTo({url:'../login/login?backpage='+backpage+'&backtype='+backtype});
        return false;
    }
    return [SUID, SRAND, SNAME, SFACE];
}
参数说明
backpage, backtype 2个参数分别代表:
backpage : 登录后返回的页面
backtype : 打开页面的类型[1 : redirectTo 2 : switchTab]
返回值说明
已经登录返回数组 [用户 id, 用户随机码, 用户昵称, 用户表情]
2、创建 login 页面
login 页面作为登录过度页面,多端登录都通过此页面完成!
3、在页面中应用登录检查函数,如 write.vue<script>
export default {
    data() {
        return {

        };
    },
    onLoad : function() {
        var loginRes = this.checkLogin('../my/my', '2');
        if(!loginRes){return false;}
    }
}
</script>
return 或终止函数运行哦!
三、UNI-APP端使用微信登录原理和条件编译
<script>
export default {
    data() {
        return {

        };
    },
    onLoad:function(){
        //app 端微信登录
        // 手册位置 https://uniapp.dcloud.io/api/plugins/login?id=getuserinfo
        // #ifdef APP-PLUS
        uni.login({
            success: (res) => {
                // res 对象格式
                //{"code":"***",
                //"authResult":{
                    //"openid":"***",
                    //"scope":"snsapi_userinfo",
                    //"refresh_token":"**",
                    //"code":"****",
                    //"unionid":"***",
                    //"access_token":"***",
                    //"expires_in":7200
                //},
                //"errMsg":"login:ok"}
                uni.getUserInfo({
                    success: (info) => {
                        // info 对象格式
                        // {"errMsg":"getUserInfo:ok",
                        // "rawData":"...
                        // "userInfo":{
                            //"openId":"***",
                            //"nickName":"***",
                            //"gender":1,
                            // "city":"Xi'an",
                            // "province":"Shaanxi",
                            // "country":"China",
                            // "avatarUrl":"头像",
                            // "unionId":"oU5Yyt_agt547zWyA0v0eLfFPqxo"
                        //},"signature":""}
                        // 与服务器交互将数据提交到服务端数据库

                    },
                    fail: () => {
                        uni.showToast({title:"微信登录授权失败"});
                    }
                })
            },
            fail: () => {
                uni.showToast({title:"微信登录授权失败"});
            }
        })
        // #endif
    }
}
</script>

四、多平台多应用 统一登录微信关系
  多平台统一登录之 unionID通过获取用户基本信息接口,开发者可通过OpenID来获取用户基本信息,而如果开发者拥有多个应用,可使用以下办法通过UnionID机制来在多个应用进行用户帐号互通。
只要是同一个微信开放平台帐号下的公众号,用户的UnionID是唯一的。
  换句话说,同一用户,对同一个微信开放平台帐号下的不同应用,UnionID是相同的。
  此前的OpenID机制,每个微信号对应每个应用有唯一的OpenID,所以不同应用之间是不能共享用户的,现在有了UnionID就可以了。
APP端获取 unionID
使用 uni.login 即可;小程序端获取 unionID

步骤 :

  1、配置小程序 appid (此appid 在微信开放平台已经绑定);

  2、使用 uni.login 登录时会获取 code,用 code 换取 seesion_key;
  3、在获取用户信息函数中获取到加密信息;
  4、利用 seesion_key 及加密信息在服务端解密获取 unionID
  php 后端注意事项需要开启 php_openssl 扩展
  前端实现过程代码export default {
    data() {
        return {

        };
    },

    methods:{
        // #ifdef MP-WEIXIN
        getUserInfo : (info) => {
            //加密数据
            var encryptedData = info.mp.detail.encryptedData;
            var iv            = info.mp.detail.iv;
            info              = info.mp.detail.userInfo;
            //info
            //userInfo {"nickName":"深海","gender":1,...avatarUrl":"https://7tdPvkPaJlkaLFFbLAffGVApluZdanLkDVplNlAhq1EJA/132"}
            //与服务器交互进行解密
            uni.request({
                url: _self.apiServer+'member&m=wxaes',
                method: 'POST',
                header: {'content-type' : "application/x-www-form-urlencoded"},
                data: {
                    session_key   : session_key,
                    encryptedData : encryptedData,
                    iv            : iv
                },
                success: res => {
                    console.log(res);
                    //此处可以成功获取 unionId 利用 unionId 完成登录即可
                },
                fail: () => {},
                complete: () => {}
            });
        }
    },
    onLoad:function(options){
            _self = this;
            pageOptions = options;
            // #ifdef MP-WEIXIN
            // 调用 微信 login 获取 code
        uni.login({
                    success: (res) => {
                        uni.request({
                            url:_self.apiServer+'member&m=codeToSession&code='+res.code,
                            success: (sessions) => {
                                session_key = sessions.data.session_key;
                            }
                        }
                    }
                });
            }
        });
        // #endif
}
php 后端代码<?php
namespace hsC;
class member{
        //......
    public function wxaes(){
        if(empty($_POST['session_key']) || empty($_POST['encryptedData']) || empty($_POST['iv'])){exit(jsonCode('error', 'data error'));}
        include HS_TOOLS.'WXBizDataCrypt.php';
        $pc = new \WXBizDataCrypt(HS_APPID, $_POST['session_key']);
        $data = '';
        $errCode = $pc->decryptData($_POST['encryptedData'], $_POST['iv'], $data);
        if ($errCode == 0) {
            exit($data);
        } else {
            exit(jsonCode('error', $errCode));
        }
    }
}
五、api接口安全策略 - 签名策略
安全概述
  前面章节讲解的接口是裸露的、不安全的!使用post、get模拟可以轻松对api进行请求,最简单的攻击就可以瞬间完成近万会员的注册!
  所以在进行api接口通讯的同时我们应该进行数据的验证工作!
  加密原理及流程1、从服务器端获取一个唯一性的token,我们称之为 accessToken;
  2、前端对accessToken进行随机性拆分及md5加密,产生签名(保存在本地存储中);
  3、前端在与后端进行交互时传递签名;
  4、后端接收数据是验证签名;
  签名准备1、在 commons 文件夹内创建1.1 md5.js //js md5 加密 [ 在课程内获取此 js文件 ]
1.2 sign.js // 签名函数
sign.jsvar md5 = require('./md5.js');
module.exports = {
    sign : function(apiServer){
        // 环境判断非uni环境不支持
        if(!uni){return '...';}
        // 连接服务器获取一个临时的accessToken
        uni.request({
            url: apiServer+'getAccessToken',
            method: 'GET',
            success: res => {
                if(res.data.status != 'ok'){return ;}
                var data = res.data.data;
                // 对 accessToken 进行md5加密
                var accessToken = md5.hex_md5(data.token + data.time);
                // 签名 = md5(accessToekn + time) + '-' + 'accessToekn';
                var sign = accessToken + '-' + data.token;
                //console.log(sign);
                // 记录在本地
                uni.setStorage({
                    key:"sign",
                    data:sign
                });
            }
        });
    }
}

数据库DROP TABLE IF EXISTS `yuedu_access_tokens`;
CREATE TABLE `yuedu_access_tokens` (
  `token` varchar(30) NOT NULL,
  `time` int(11) DEFAULT NULL,
  PRIMARY KEY (`token`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;

php 端代码<?php
//getAccessToken.php
namespace hsC;
class getAccessToken{
    public function index(){
        $db = \hsTool\db::getInstance('access_tokens');
        $token = array(
            'token' => uniqid(),
            'time'  => time()
        );
        $db->add($token);
        exit(jsonCode('ok', $token));
    }
}
  使用说明
  在数据提交页面提交之前进行预签名,提交数据时携带此签名!
  更合理的签名保存
  因为大家后端基础不一样,本课程使用数据库保存了accessToken,更好的方式是 redis 或 memcache,可以设置变量有效期并能自动失效!

  • uniapp三种请求后台接口的方法
    个人总结的uniapp三种请求后台接口的方法,亲自测试过,都可以使用,建议使用第三种。
  • uniapp开发小程序样式布局无法横向排列
    今天在开发小程序前端时候,碰到一个问题,想实现横向布局flex,但是始终无法实现,最后查到是因为<scroll-view>不支持flex。
  • uniapp如何导入uni-search-bar搜索栏组件
    最近用uniapp开发一套微信小程序商城,偶然发现uniapp可以直接导入uni-search-bar搜索栏组件,下面是方法步骤。
  • uniapp开发微信小程序如何引用animate.css
    最近用uniapp开发微信小程序的过程中想引用animate.css,下面是引用方法。
  • 网站制作报价单模板适用多个行业(最新版)
    网站制作报价免费模板下载,可以应用于多个行业,也可以根据客户需求进行定制,内容详细,报价清晰明确,直接复制即可使用。
  • bootstrap网站制作案例实训——开发电商网站特效
    本案例使用Bootstrap进行网站制作的网格系统进行布局,其中设置了一些电商网站经常出现的动画效果。
  • 网站制作报价预算的明细报表下载,免费使用
    本文为大家提供网站制作报价预算的明细报表,内容包括网站制作原报价价格、根据客户要求进行修改、网站制作调整后报价,免费下载。
  • bootstrap被删除的Glyphicons字体图标
    本文单独介绍一下Bootstrap框架中的Glyphicons字体图标组件。Glyphicons字体图标指的是Glyphicon Halflings字体图标。我们在使用Glyphicons Halflings字体图标时一般是需要付费的,不过Glyphicons Halflings字体图标拥有者对Bootstrap授权可以免费使用。
  • 苏州网站制作报价,苏州网站建设价格
    苏州网站建立几钱,苏州网站制造的价钱规范,真的很重要、很迫切需求吗?当你散步市场时,你发现同一件商品在每一个摊位的报价都不同时,你能否在犹疑?这时你就是客户,你弄不分明终究花几钱购置该商品才是最合算,由于该市场没有标准。
  • Three.js网站开发指南:在单几何体上使用多种材质
    在创建THREE.Mesh时,到目前为止,我们已经使用过一种材质。为几何体的每个面指定不同的材质是可能的。
  • 网站制作 服务

    免费网站制作报价,免费优化,1对1服务,个性化定制服务

    pc和wap网站制作

    多年建站经验,上千个成功案例,
    为您提供一站式服务

    网站维护改版

    大厂经验工程师对现有网站进行
    改版,修复,维护。

    小程序制作

    微信小程序,支付宝小程序,
    百度小程序

    响应式网页设计

    响应式网页设计可以与多种设备兼容,
    如智能手机,平板电脑和PC