开发
- 开发工具。基本分为三块
(1) Table-item 界面的页数。
(2) Webview 页面在这里实时展示。
(3) Chrome调试工具。
- 基本文件。
(1)js 脚本文件。监听并处理小程序的生命周期函数、声明全局变量。调用框架提供的APi(应用程序接口)
(2)json 配置文件。是对小程序的全局配置。可以配置背景色,页面组成,导航条样式。 注意:该文件不能添加任何注释。
(3)wxss样式表文件。是小程序的公共样式表。比如我们可以在页面的 class属性直接使用 app.wxsss声明的样式规则。
//app.jsApp({onLaunch: function () {//调用API从本地缓存中获取数据var logs = wx.getStorageSync('logs') || []logs.unshift(Date.now())wx.setStorageSync('logs', logs)},getUserInfo:function(cb){var that = this;if(this.globalData.userInfo){typeof cb == "function" && cb(this.globalData.userInfo)}else{//调用登录接口wx.login({success: function () {wx.getUserInfo({success: function (res) {that.globalData.userInfo = res.userInfo;typeof cb == "function" && cb(that.globalData.userInfo)}})}});}},globalData:{userInfo:null}})//app.json 是对整个小程序的全局配置。我们可以在这个文件中配置小程序是由哪些页面组成,//配置小程序的窗口背景色,配置导航条样式,配置默认标题。注意该文件不可添加任何注释。//更多可配置项可参考配置详解。{"pages":["pages/index/index","pages/logs/logs"],"window":{"backgroundTextStyle":"light","navigationBarBackgroundColor": "#fff","navigationBarTitleText": "WeChat","navigationBarTextStyle":"black"}}app.wxss 是整个小程序的公共样式表。我们可以在页面组件的 class 属性上直接使用 app.wxss 中//声明的样式规则。/**app.wxss**/.container {height: 100%;display: flex;flex-direction: column;align-items: center;justify-content: space-between;padding: 200rpx 0;box-sizing: border-box;}创建页面//有两个页面,index 页面和 logs 页面,即欢迎页和小程序启动日志的展示页,他们都在 pages 目录下。//微信小程序中的每一个页面的【路径+页面名】都需要写在 app.json 的 pages 中,且//pages 中的第一个页面是小程序的首页。每一个小程序页面是由同路径下同名的四个不同后缀文件的组成,如:index.js、index.wxml、//index.wxss、index.json。.js后缀的文件是脚本文件,.json后缀的文件是配置文件,//.wxss后缀的是样式表文件,.wxml后缀的文件是页面结构文件。index.wxml 是页面的结构文件:<!--index.wxml--><view class="container"><view bindtap="bindViewTap" class="userinfo"><image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image><text class="userinfo-nickname">{{userInfo.nickName}}</text></view><view class="usermotto"><text class="user-motto">{{motto}}</text></view></view>//index.js 是页面的脚本文件,在这个文件中我们可以监听并处理页面的生命周期函数、获取小程序实例,//声明并处理数据,响应页面交互事件等。//index.js//获取应用实例var app = getApp()Page({data: {motto: 'Hello World',userInfo: {}},//事件处理函数bindViewTap: function() {wx.navigateTo({url: '../logs/logs'})},onLoad: function () {console.log('onLoad')var that = this//调用应用实例的方法获取全局数据app.getUserInfo(function(userInfo){//更新数据that.setData({userInfo:userInfo})})}})//index.wxss 是页面的样式表:/**index.wxss**/.userinfo {display: flex;flex-direction: column;align-items: center;}.userinfo-avatar {width: 128rpx;height: 128rpx;margin: 20rpx;border-radius: 50%;}.userinfo-nickname {color: #aaa;}.usermotto {margin-top: 200px;}
选择微信小程序模式,需要自行下载并打开微信开发者工具,然后选择项目根目录进行预览。
微信小程序编译预览及打包(去掉 —watch 将不会监听文件修改,并会对代码进行压缩打包)
# npm script$ npm run dev:weapp$ npm run build:weapp# 仅限全局安装$ taro build --type weapp --watch$ taro build --type weapp# npx 用户也可以使用$ npx taro build --type weapp --watch$ npx taro build --type weapp
架构
session+cookie
- Session和Cookie都是由服务器生成的。
- Session和Cookie都是键值对形式保存,主要用于存储特定的一些状态值。
- Session保存在服务器,Cookie保存在客户端。通常,Session的ID会以Cookie的形式返回给客户端的。
- Session和Cookie都是有生命周期的。Cookie的生命周期受到Cookie自身的有效期和客户端的影响,一般来说,浏览器(客户端)是会自动将存活的Cookie封装在请求头里面,向服务器发送。如果Cookie有效期过期或客户端清理了Cookie,则发送的请求中就没有Cookie值;Session的生命周期受到Session自身的有效期和客户端是否关闭的影响。SessionID虽然是已Cookie的形式返回给客户端,但是它是不受客户的Cookie容器的管理,而是和客户端进程有关,即客户端进程不关闭,一般Session在客户端就不会失效。
- Session和Cookie都是有作用域的
- cookie
如果是POST方式访问,从提交过来的数据中验证用户是否登录成功,登录成功便将用户名设置到cookie,并且返回给客户端,进入欢迎页。
如果是GET方式访问,则从访问的cookie中获取用户信息,如果从cookie中能获取到用户名,则认为用户已登录,返回欢迎页
- session
如果是POST方式访问,从提交过来的数据中验证用户是否登录成功,登录成功便将用户名设置到Session中,并且返回给客户端,进入欢迎页。
如果是GET方式访问,则从访问的Session中获取用户信息,如果从Session中能获取到用户名,则认为用户已登录,返回欢迎页
cookie比session更容易受攻击
- Alex80/p:第三方登陆
- shanzhonglei./?p:登录态维护

1、在客户端获取当前登录微信用户的登录凭证(code)
我们可以使用wx.login获得一个微信用户登录的临时凭证,这个操作可以在App.js中执行,也可以在页面文件中执行,根据业务需求来选择。
App({onLaunch: function() {wx.login({success: function(res) {var code = res.code;if (code) {console.log('获取用户登录凭证:' + code);} else {console.log('获取用户登录态失败:' + res.errMsg);}}});}})
2、将临时code发送我们的服务器,在服务器端向微信服务器换取该用户的唯一标识(openid)和会话密钥(session_key)
App({onLaunch: function() {wx.login({success: function(res) {var code = res.code;if (code) {console.log('获取用户登录凭证:' + code);// --------- 发送凭证 ------------------wx.request({url: 'https://www.shanzhonglei.com/wx/login',data: { code: code }})// ------------------------------------} else {console.log('获取用户登录态失败:' + res.errMsg);}}});}})
在我们的服务器后台,需要使用这个code来换取该用户的唯一标识(openid)和会话密钥(session_key)。这个openid是用户的唯一标识,是微信用户在小程序生态中唯一的标识。值得注意的是:
会话密钥session_key 是对用户数据进行加密签名的密钥。
为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。
临时登录凭证code只能使用一次。
临时登录凭证校验接口是一个HTTPS接口。
接口地址:
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
后端代码构建:
const Koa = require('koa');const Router = require('koa-router');const bodyParser = require('koa-bodyparser');const request = require('request');const app = new Koa();const router = new Router();app.use(bodyParser());// 配置文件const minproSetting = require('./config');// 路由处理router.get('/', (ctx, next) => {// 获取codelet code = ctx.query.code;let queryData = ctx.query;debugger;let url = `https://api.weixin.qq.com/sns/jscode2session?appid=${minproSetting.appid}&secret=${minproSetting.appsecret}&js_code=${code}&grant_type=authorization_code`request({ method: 'GET', url: url, json: true }, function (error, response, body) {// 验证获取的数据const exporesIn = body.expores_in;const openid = body.openid;const session_key = body.session_key;})});app.use(router.routes()).use(router.allowedMethods());app.listen(8888);
请不要直接使用这些信息作为小程序的用户标识和session标识回传到小程序客户端。在服务器端应该把openid和session_key进行封装成sessionid,把sessionid派发到小程序客户端作为session来使用的。在服务端做session机制,我们一般使用键值对存储工具来做,比如redis,为了安全,应该设置一个超时的时间。
3、在客户端保存sessionid
在开发web应用的时候,我们通常是将sessionid存在cookie中,但是小程序是没有cookie机制的,所以不能采用cookie了,但是小程序有本地的storage,我们可以使用storage来保存sessionid,之后调用那些需要登录才有权限访问的后台服务时,就把sessionid从本地读取出来,放在请求中发至后台。后台服务需要验证sessionid的有效性,我们可以使用自定义中间件来验证。
在小程序中每次调用后台业务API的时候,先使用wx.checkSession()来检查会话是否过期,如果已过期,则重新调用建立会话的代码流程,然后再调用目标业务API;如果未过期,则直接调用业务API。
如果系统对数据安全要求不高的话,也可以不采用session机制。第一次登录生成sessionid后返回给用户并存到storage中,以后每次后台请求都读取storage,如果读取不到storage,则重新走以一遍登录流程生成sessionid
完整过程
1、在客户端获取当前登录微信用户的登录凭证(code)我们可以使用wx.login获得一个微信用户登录的临时凭证,这个操作可以在App.js中执行,也可以在页面文件中执行,根据业务需求来选择。App({onLaunch: function() {wx.login({success: function(res) {var code = res.code;if (code) {console.log('获取用户登录凭证:' + code);} else {console.log('获取用户登录态失败:' + res.errMsg);}}});}})2、将临时code发送我们的服务器,在服务器端向微信服务器换取该用户的唯一标识(openid)和会话密钥(session_key)App({onLaunch: function() {wx.login({success: function(res) {var code = res.code;if (code) {console.log('获取用户登录凭证:' + code);// --------- 发送凭证 ------------------wx.request({url: 'https://www.shanzhonglei.com/wx/login',data: { code: code }})// ------------------------------------} else {console.log('获取用户登录态失败:' + res.errMsg);}}});}})在我们的服务器后台,需要使用这个code来换取该用户的唯一标识(openid)和会话密钥(session_key)。这个openid是用户的唯一标识,是微信用户在小程序生态中唯一的标识。值得注意的是:会话密钥session_key 是对用户数据进行加密签名的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。临时登录凭证code只能使用一次。临时登录凭证校验接口是一个HTTPS接口。接口地址:https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code后端代码构建:const Koa = require('koa');const Router = require('koa-router');const bodyParser = require('koa-bodyparser');const request = require('request');const app = new Koa();const router = new Router();app.use(bodyParser());// 配置文件const minproSetting = require('./config');// 路由处理router.get('/', (ctx, next) => {// 获取codelet code = ctx.query.code;let queryData = ctx.query;debugger;let url = `https://api.weixin.qq.com/sns/jscode2session?appid=${minproSetting.appid}&secret=${minproSetting.appsecret}&js_code=${code}&grant_type=authorization_code`request({ method: 'GET', url: url, json: true }, function (error, response, body) {// 验证获取的数据const exporesIn = body.expores_in;const openid = body.openid;const session_key = body.session_key;})});app.use(router.routes()).use(router.allowedMethods());app.listen(8888);请不要直接使用这些信息作为小程序的用户标识和session标识回传到小程序客户端。在服务器端应该把openid和session_key进行封装成sessionid,把sessionid派发到小程序客户端作为session来使用的。在服务端做session机制,我们一般使用键值对存储工具来做,比如redis,为了安全,应该设置一个超时的时间。3、在客户端保存sessionid在开发web应用的时候,我们通常是将sessionid存在cookie中,但是小程序是没有cookie机制的,所以不能采用cookie了,但是小程序有本地的storage,我们可以使用storage来保存sessionid,之后调用那些需要登录才有权限访问的后台服务时,就把sessionid从本地读取出来,放在请求中发至后台。后台服务需要验证sessionid的有效性,我们可以使用自定义中间件来验证。在小程序中每次调用后台业务API的时候,先使用wx.checkSession()来检查会话是否过期,如果已过期,则重新调用建立会话的代码流程,然后再调用目标业务API;如果未过期,则直接调用业务API。如果系统对数据安全要求不高的话,也可以不采用session机制。第一次登录生成sessionid后返回给用户并存到storage中,以后每次后台请求都读取storage,如果读取不到storage,则重新走以一遍登录流程生成sessionid
