一、项目介绍
课程内容项目页面说明
二、创建项目、后端环境介绍
- 创建项目
- 打开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"
}
]
}
- 修改项目名称
"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
return 或终止函数运行哦!
四、UNI-APP端使用微信登录原理和条件编译
四、部署php环境
1、集成环境 phpstudy 安装
phpstudy 下载地址
http://phpstudy.php.cn/
修改时间php.ini 配置
date.timezone = PRC //中国时区
2、固定内网ip
开始 > 设置 > 网络和internet > 以太网 > 更改适配器属性 在以太网图标 > 右键 > 状态 > 详细信息
注意 : localhost 代表本机,手机中 localhost 代表手机自己并不能代表内网服务器!
获取内网ip规则,如 : 192.168.1.***。
修改ipv4地址,固定内网ip:
开始 > 设置 > 网络和internet > 以太网 > 更改适配器属性 在以太网图标 > 右键 > 属性 > ipv4 地址 > 点击修改,如 : 192.168.1.188
修改后测试网络畅通即可!
浏览器访问 http://192.168.1.188/ 即可直接访问刚刚搭建的php环境 ;
3、部署基础php 代码
我们为大家精心准备了一个极小的基础开发库,请大家在课程内下载并部署至 php 环境的根目录;
4、基础开发库原理详解
路由解析例子
'hcoder');
echo jsonCode('ok', $res);
//输出字符串 {"status":"ok","data":{"name":"hcoder"}}
//创建test类 getUser函数
getUser();
最后打开phpStudy》phpMyAdmin 默认用户密码root
创建名字xxx的数据库
五、创建用户数据表,完成app端用户登录功能
1、创建项目数据库
1.1 打开 phpMyadmin 或者其他 mysql 管理工具,phpstudy 环境下 mysql 账户 root 密码 root;
1.2 创建数据库 "yuedu"
CREATE TABLE `yuedu_members` (
`u_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`u_openid` varchar(100) NOT NULL COMMENT 'openid',
`u_name` varchar(50) NOT NULL COMMENT '用户昵称',
`u_face` varchar(200) NOT NULL COMMENT '用户头像',
`u_random` varchar(30) NOT NULL COMMENT '用户随机码',
`u_integral` int(10) DEFAULT '0' COMMENT '积分',
`u_remainder` int(10) DEFAULT '0' COMMENT '余额',
`u_regtime` int(11) NOT NULL COMMENT '用户注册时间',
PRIMARY KEY (`u_id`),
UNIQUE KEY `u_openid` (`u_openid`),
UNIQUE KEY `u_id` (`u_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
2、phpMyAdmin 错误修正
Fatal error: Cannot 'break' 2 levels in D:\phpStudy\PHPTutorial\WWW\phpMyAdmin\export.php on line 590
590 行把 break 2 改成 break;
3、配置数据库
打开 index.php 修改以下配置
/* 数据库配置 */
define('HS_DB_HOST' , '127.0.0.1'); // mysql 服务器地址
define('HS_DB_NAME' , 'yuedu'); // 数据库名称
define('HS_DB_USER' , 'root'); // 数据库账号
define('HS_DB_PWD' , 'root'); // 数据库密码
define('HS_DB_PRE' , 'yuedu_'); // 数据表统一前缀
define('HS_DB_CHARSET' , 'utf8mb4'); // mysql 字符集类型
4、创建 member 控制器,编写以下代码:
login();
}
}
// 原理见视频教程
5、在 app 端定义全局变量,定义全局的 api 接口地址及token
var APITOKEN = 'api2018';
Vue.prototype.apiServer = 'http://192.168.1.188/index.php?token='+APITOKEN+'&c=member&m=login';
为什么这样定义? 便于后期修改!
- 如果手机端无法访问局域网ip,如何解决?
方案1、使用花生壳软件 > 内网穿透(功能收费6元)
方案2、使用模拟器调试,模拟器下载地址 :
方案3、将后端api 部署到公网服务器上
6、login.vue 与api交互完成app端登录功能
六、完成小程序端登录
1、在uniapp中配置小程序appid
打开 manifest.json ,找到微信小程序配置,填写 appid 重启应用;
// 您需要注册成为微信小程序开发者才能获取 appid
2、视图添加登录按钮
3、js 核心代码
php 后端代码
login();
}
public function codeToSession(){
if(empty($_GET['code'])){exit(jsonCode('error', 'code error'));}
$url = "https://api.weixin.qq.com/sns/jscode2session?appid=".HS_APPID.
"&secret=".HS_SECRET."&js_code=".$_GET['code']."&grant_type=authorization_code";
$curl = new \hsTool\curl();
$res = $curl->get($url);
echo $res;
}
}
七、多平台多应用 统一登录微信关系
多平台统一登录之 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 后端代码
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.js
var 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 端代码
uniqid(),
'time' => time()
);
$db->add($token);
exit(jsonCode('ok', $token));
}
}
使用说明
在数据提交页面提交之前进行预签名,提交数据时携带此签名!
更合理的签名保存
因为大家后端基础不一样,本课程使用数据库保存了accessToken,更好的方式是 redis 或 memcache,可以设置变量有效期并能自动失效!
九、在登录环节使用签名验证策略
后端验证签名原理
// 前端使用签名验证
十、完成写作页面布局
页面功能
1、基础布局
2、文章内容展示
3、添加图片
4、添加文本
5、动态展示提交按钮
完整代码
删除
文章分类
{{caties[currentCateIndex]}}
发布文章
分类数据表
DROP TABLE IF EXISTS `yuedu_categories`;
CREATE TABLE `yuedu_categories` (
`cate_id` int(10) NOT NULL AUTO_INCREMENT,
`cate_pid` int(10) DEFAULT '0',
`cate_name` varchar(50) DEFAULT NULL,
`cate_order` int(10) DEFAULT NULL,
PRIMARY KEY (`cate_id`),
KEY `cate_pid` (`cate_pid`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Records of yuedu_categories
-- ----------------------------
INSERT INTO `yuedu_categories` VALUES ('1', '0', '美文', '1');
INSERT INTO `yuedu_categories` VALUES ('2', '0', '互联网', '2');
INSERT INTO `yuedu_categories` VALUES ('3', '0', '汽车', '3');
后端代码
order('cate_order asc')->fetchAll();//没有pid就查询所有分类
}else{
$categories = $db->order('cate_order asc')->where('cate_pid = ?', array($_GET['pid']))->fetchAll();
}//有pid就查询子分类
if(empty($categories)){exit(jsonCode('empty', ''));}//如果是空的就输出空
$caties = array();
foreach($categories as $cate){
$caties[$cate['cate_id']] = $cate['cate_name']; //如果不是空就把数据传入数组caties
}
exit(jsonCode('ok', $caties));//输出caties
}
}
后续代码可查看
http://www.hcoder.net/tutorials/info_1380.html