摘要:踩過微信小程序坑的人都知道,微信小程序是不支持的。微信小程序采用的是獲取,通過開發者服務器端同微信服務器進行數據交互實現登錄。具體參考微信相關文檔,這里不贅述。而且萬一哪天微信小程序支持了呢,采用方式,還是和以前一樣操作數據。
?????????踩過微信小程序坑的人都知道,微信小程序是不支持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:以上為項目部分代碼,不保證能夠完全運行。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95262.html
摘要:前言微信小程序中可以直接運行頁面,這一新組件的產生,可能直接導致小程序數量迎來一波高峰。微信小程序配置系列問題配置域名業務域名中配置的就是小程序以及和中引用的域名。 今日勵志語 要接受自己行動所帶來的責任而非自己成就所帶來的榮耀。 前言 微信小程序中可以直接運行 web 頁面,這一新組件 web-view 的產生,可能直接導致小程序數量迎來一波高峰。本篇博文將從業務選型,微信小程序后臺...
閱讀 2675·2023-04-25 15:15
閱讀 1316·2021-11-25 09:43
閱讀 1604·2021-11-23 09:51
閱讀 1079·2021-11-12 10:36
閱讀 2880·2021-11-11 16:55
閱讀 955·2021-11-08 13:18
閱讀 723·2021-10-28 09:31
閱讀 2048·2019-08-30 15:47