小程序登录和Seesion
微信小程序是没有Cookie的,而维护用户登录状态需要使用Session机制,我们先来看看小程序的登录流程。
从图中可以得知,开发者服务器在完成Session的工作中起到了一个中介的作用:根据小程序的code,向微信接口服务发起请求,获取session_key 和 openid,接着在开发者服务器上对session_key和openid进一步处理,搭建开发者服务器自身的session,也就是自定义登录状态,接着返回给客户端,以后客户端向开发者服务器发请求时需要携带这些登录状态信息。
node服务器处理session的中间件
express-session
:https://github.com/jmFang/sessionexpress-mysql-session:
:https://github.com/jmFang/express-mysql-session
以上俩中间件的相信介绍可查看GitHub。
使用中间件的处理session,可以省去了很多工作,例如,监视session的过期时间,及时清理session;
配合mysql
数据库,及其相关中间件,事半功倍。
引入中间件
var session = require('express-session'); var MySQLStore = require('express-mysql-session')(session);
配置
var options = { host:'localhost', port:'3306', user:'root', password:'rootpass', database:'session_test', checkExpirationInterval:60000, //一分钟检查一次 expiration: 3600000, //最大的生命期 connectionLimit: 1, schema: { tableName: 'sessions', //表名 columnNames: { //列 session_id: 'session_id', expires: 'expires', data: 'data' } } };
schema: 配置数据表
操作Session数据库表的MySQL实例
var sessionStore = new MySQLStore(options);
使用Session中间件
app.use(session({ key: 'mgyusys', //自行设置密钥 secret: 'sysuygm', //私钥 cookie: { maxAge: 60000 //最大生命期 }, store: sessionStore, //存储管理器 resave: false, saveUninitialized: false }));
开发者服务器的登录路由
route.get('/login', function(req, res, next) { var code = req.query.code; var cookies = req.cookies; //生成当前服务器时间 var curTime = moment().format("YYYY-MM-DD HH:mm:ss"); // 向微信服务器请求sesion_key request.get({ url:"https://api.weixin.qq.com/sns/jscode2session", json:true, qs:{ grant_type:'authorization_code', appid:config.appid, secret:config.secret, js_code:code } }, function(err, resp, data) { if (resp.statusCode == 200) { var sessionKey = String(data.session_key); var openId = data.openid; //自定义的加密,作为session_id var skey = sha1(sessionKey); var data = { lastTime:curTime, curTime:curTime, cookies:cookies } var sessionData = { session_id:skey, expires:60000, data: JSON.stringify(data) }; //session的MySQL管理器,设置session(如果session_id不存在,则写入数据库) sessionStore.set(skey,sessionData, function (err) { if(err) console.log(err) }) //返回给客户端 res.json({session_data:sessionData}) } else { res.json(err) } }) })
客户端请求登录
wx.login({ success:function(res) { if(res.code) { console.log("res.code",res.code) wx.request({ url: 'https://服务器域名/login', data:{ code:res.code }, method:"GET", success:function(res) { console.log(res) var session_data = res.data.session_data; var session_id = session_data.session_id; var expires = session_data.expires; var data = session_data.data; //将session_id保存到本地数据库 wx.setStorageSync('session_id', session_id) } }) } else { console.log("获取用户登录状态失败"+ res.errMsg); } }, complete:function(e) { console.log("获取用户登录成功" + e.toString()); } });
(完)