基于Node.js的微信小程序cookie解决方案

元胞星云
• 阅读 3905

         踩过微信小程序坑的人都知道,微信小程序是不支持cookie的。微信小程序采用的是wx.login获取code,通过开发者服务器端同微信服务器进行数据交互实现登录。得到openid或者unionid与本地数据库关联,从而得到登录用户相关信息。

         具体参考微信相关文档wx.login,这里不赘述。

         通常情况下,我们不仅仅是需要用户数据,还需要用户的登录状态,也就是session和cookie机制。要命的是小程序不支持cookie,没有了cookie,session也无从谈起。这里基于node.js的express和koa,通过header头添加标记的方式,模拟cookie,从而在服务器端引入session。

         cookie的本质是唯一字符串标记,由浏览器自动生成(这里是作为会话方案,而非数据存储方案而言)。既然是唯一字符串标记,那我们也可以自己生成一个类似的标记,添加到Headers头中,类似这样

let header={'x-xxxx-cookie':'uuid cookie'};
//
wx.request({
    url:url,
    data:data,
    header:header,
    method:method,
    success: function( res ) {
        
    },
    fail: function( error ) {
    
    }
});

         需要注意的是,这里的uuid cookie最好使用服务器端的session ID,后面再说为什么?

         以上就是前端(小程序端)的处理,接下来是服务器端的处理,服务器端使用的是express或者koa,具体使用请移步:
         Express
         Koa

         服务器端Express中session使用的是express-session,Koa中使用的是koa-generic-session,对于Koa这里多说一句,原本也打算使用koa-session,最后放弃选择了前者,因为后者没有暴露出类似获取session ID的参数,而整个过程中需要获取到session ID非常重要。session存储都使用Redis。
Express部分代码如下:

var express = require('express');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var RedisStore = require('connect-redis')(session);

//
var sessionStore=new RedisStore({
    host:config.redis.host,
    port:config.redis.port
});
var app = express();
//
app.use(cookieParser());

//cookie
var cookieParser=cookieParser(config.secret);
app.use(cookieParser);

//session
var sessionParser = session({
    store:sessionStore,
    secret:config.secret,
});
app.use(sessionParser);    

//

Koa部分代码:

const Koa  = require('koa');
const session = require('koa-generic-session');
//const session = require('koa-session');
const RedisStore = require('koa-redis');
//
const app = new Koa();

// middlewares
app.use(bodyparser({
  enableTypes:['json', 'form', 'text']
}));
//
let sessionStore=new RedisStore(sessionRedisOptions);
let sessionOptions={
    store: sessionStore,
    key: '',
};
//
const sessionParser = session(sessionOptions,app);
app.use(sessionParser);

         获取session ID,Express中可以直接通过req.sessionID获取得到,koa中使用ctx.sessionId获取得到。之所以session ID重要,主要是我们可以直接通过它获取到session。如果不使用session ID的方式的话,我们需要自己额外去存储相关数据,可以不用将数据挂载到req.session或者ctx.session上,会带来额外的代码成本。而且万一哪天微信小程序支持cookie了呢,采用session ID方式,还是和以前一样操作session数据。

         我们需要将session ID从服务器端返回到小程序端,通常会在第一个请求的时候就返回,然后小程序端将该数据保存,类似这样:

    app.globalData.cookieID=uuid cookie;//uuid cookie为服务器端返回的session ID

         小程序端以后的请求都将该数据添加到Headers头中传递到服务器端。

         服务器端下一个请求,直接通过req.session或者ctx.session还是获取不到之前设置的session数据啊!
         的确是的,我们需要在路由之前,添加一个中间件来解决。类似这样:
Express部分代码:

app.use(function(req,res,next){
    //
    var sessionID=req.headers['x-xxxx-cookie'];
    if(sessionID){
        //
        return sessionStore.get(sessionID,function(err,session){
            //
            req.session=Object.assign(req.session||{},session||{});
            //
            next();
        });
    }
    //
    next();
});

Koa部分代码:

app.use(async function (ctx,next){
    //
    var cookies=ctx.cookies;
    var sessionID=ctx.request.headers['x-xxxx-cookie']||cookies.get(sessionOptions.key);
    if(sessionID){
        //
        let sess= await ctx.sessionStore.get(sessionID);
        //
        let session=Object.assign(ctx.session||{},sess||{});
        ctx.session=session;
    }
    //
    await next();
});

         也就是我们需要通过session ID得到session,然后赋值到req.session或者ctx.session上,保证之后可以直接按照普通方式操作session数据。

         好了,就到这里,总结一下:
         通过header添加类cookie唯一字符串标记,而该字符串标记直接对应服务器端session ID,可以在服务器端直接通过session ID获取到session数据,利用中间件将获取到的session数据赋值给request,从而实现小程序端就像支持cookie一样。

         如果引入了socket,比如ws,个中过程又要复杂一些,额外引入其他坑需要填埋,下回再表。

PS:以上为项目部分代码,不保证能够完全运行。

点赞
收藏
评论区
推荐文章
小森森 小森森
2年前
计划助手V1.0-微信小程序(QQ小程序)-源代码分享
疫情期间在家感觉好无聊啊,于是利用空闲时间做了一个用来记录和管理小目标时间的小程序,命名为《小沙漏》。QQ版本小程序同步上线,QQ小程序叫《时间小沙漏》,欢迎大家前来体验,后期也会添加其他的新功能哦【区别】:微信小程序的代码与QQ小程序的源码是不一样的。微信小程序的源码基于微信小程序云开发,需要在有网络的情况下使用,具有同步功能,所有记录在删除小
胡哥有话说 胡哥有话说
4年前
微信小程序支付功能全流程实践
前言微信小程序为电商类小程序,提供了非常完善、优秀、安全的支付功能。在小程序内可调用微信的API完成支付功能,方便、快捷。小程序开发者在开发小程序时,支付流程是必然要接触到,今天胡哥就小程序支付的全流程为大家一一细说,让小伙伴能快速得掌握小程序支付能力,避免踩坑!知己知彼,方能百战不殆小程序支付流程图小程序支付交互流程图(https:/
马丁路德 马丁路德
4年前
小程序静默登录与维护自定义登录态
1.背景在小程序中,openid是一个用户对于一个小程序/公众号的标识,开发者可以通过这个标识识别出用户,就如同你的身份证一样。2.什么是静默登录?在普通的应用中,用户通过表单验证登录建立用户体系,这种常见的登录方式一般是通过登录页面表单进行登录,对用户来说是有感的。在小程序中,由于是基于微信,可以通过微信官方提供的API能力,使我们能够无感知得获取
放学路上 放学路上
3年前
微信小程序事件传参与vue传参的不同
1、vue点击事件传参(day)的写法:2、微信小程序写法(1)事件传参(2)获取参数dayprocess(e)console.log(e.currentTarget.dataset.day)3、总结:微信小程序不支持事件传参,可以通过把参数绑定在元素上,通过currentTarget.dataset获取参数。
梦
4年前
微信小程序modal
首先创建一个组件component,组件命名可以为modalmodal.wxml的内容为<viewclass'modalmask'wx:if'{{show}}'bindtap'clickMask'<viewclass'modalcontent'<scrollviewscrollyclass'mainc
Wesley13 Wesley13
3年前
5G消息与微信小程序互联互通?北京国都互联这么做……
最近微信小程序上线了一个超级流量的新入口URLScheme,据微信官网介绍,scheme码适用于短信、邮件、外部网页等拉起小程序的业务场景。通过小程序页面的URLScheme,可以在短信、邮件或微信外部的网页中打开微信小程序。意义在于将微信流量生态延伸到微信以外渠道,进一步完善了小程序和外部渠道互通的营销场景。北京国都互联第一时
Stella981 Stella981
3年前
HotApp小程序统计云后台 免费的Https云后台服务器
小程序学习有些地方需要后台,比如需要存储数据到服务器,比如微信登录。hotapp有免费的小程序云后台包含基本的新增,查询,修改,删除操作,方便于学习,而且不需要微信appid也可使用。小程序微信手机调试appid,简单解决办法:http://www.wxappunion.com/forum.
Wesley13 Wesley13
3年前
10分钟上线
_摘要:_ 阿里云函数计算是一个事件驱动的全托管计算服务。通过函数计算,您无需管理服务器等基础设施,只需编写代码并上传。微信小程序是一种不需要下载安装即可使用的应用,它可以在微信内被便捷地获取和传播。当微信小程序遇见serverless,他们会产生奇妙火花,利用函数计算可以快速搭建微信小程序的serverle.点此查看原文:http://clic
使用taro+canvas实现微信小程序的图片分享功能 | 京东云技术团队
业务场景二轮充电业务中,用户充电完成后在订单详情页展示订单相关信息,用户点击分享按钮唤起微信小程序分享菜单,将生成的图片海报分享给微信好友或者下载到本地,好友可通过扫描海报中的二维码加群领取优惠。使用场景及功能:微信小程序生成海报图片分享好友下载图片使用技