mirror of
https://github.com/thinkjs/thinkjs.git
synced 2026-01-25 14:42:47 +00:00
166 lines
4.4 KiB
JavaScript
166 lines
4.4 KiB
JavaScript
var crypto = require('crypto');
|
||
/**
|
||
* 生成uid
|
||
* @param int length
|
||
* @return string
|
||
*/
|
||
var uid = function(length){
|
||
var ratio = Math.log(64) / Math.log(256);
|
||
var numbytes = Math.ceil(length * ratio);
|
||
var str = crypto.randomBytes(numbytes).toString('base64').slice(0, length);
|
||
return str.replace(/\+/g, '_').replace(/\//g, '-');
|
||
};
|
||
/**
|
||
* 生成cookie签名
|
||
* @param string val
|
||
* @param string secret
|
||
* @return string
|
||
*/
|
||
var cookieSign = function(val, secret){
|
||
secret = crypto.createHmac('sha256', secret).update(val).digest('base64');
|
||
secret = secret.replace(/\=+$/, '');
|
||
return val + '.' + secret;
|
||
};
|
||
/**
|
||
* 解析cookie签名
|
||
* @param {[type]} val
|
||
* @param {[type]} secret
|
||
* @return {[type]}
|
||
*/
|
||
var cookieUnsign = function(val, secret){
|
||
var str = val.slice(0, val.lastIndexOf('.'));
|
||
return cookieSign(str, secret) === val ? str : false;
|
||
}
|
||
|
||
/**
|
||
* 定时器
|
||
* @type {Number}
|
||
*/
|
||
var gcTimer = 0;
|
||
/**
|
||
* 清除已经过期的session数据
|
||
* @return {[type]} [description]
|
||
*/
|
||
var gc = function(instance){
|
||
if (APP_DEBUG || APP_MODE || gcTimer) {
|
||
return;
|
||
};
|
||
//超时时间
|
||
var timeout = Math.max(24 * 3600 * 1000, C('cookie_expires'));
|
||
gcTimer = setInterval(function(){
|
||
var hour = (new Date).getHours();
|
||
//早上四点清理
|
||
if (hour !== 4) {
|
||
return;
|
||
};
|
||
var now = Date.now();
|
||
instance.gc && instance.gc(now, timeout);
|
||
}, 3600 * 1000);
|
||
}
|
||
|
||
/**
|
||
* 存储session的数据变量
|
||
* @type {Object}
|
||
*/
|
||
var session_data = {};
|
||
var Session = module.exports = Class(function(){
|
||
return {
|
||
cookie: null,
|
||
init: function(http){
|
||
this.http = http;
|
||
//session_cookie是未签名的cookie
|
||
this.cookie = http.session_cookie;
|
||
gc(this);
|
||
this.afterInit && this.afterInit();
|
||
},
|
||
/**
|
||
* 差异化的init放在这里实现
|
||
* @return {[type]} [description]
|
||
*/
|
||
afterInit: function(){
|
||
if (!(this.cookie in session_data)) {
|
||
session_data[this.cookie] = {};
|
||
};
|
||
},
|
||
/**
|
||
* 获取session,返回一个promise
|
||
* @param {[type]} name
|
||
* @return {[type]}
|
||
*/
|
||
get: function(name){
|
||
session_data[this.cookie].__ACTIVE_TIME__ = Date.now();
|
||
var value = session_data[this.cookie][name] || "";
|
||
return getPromise(value);
|
||
},
|
||
/**
|
||
* 设置session
|
||
* @param {[type]} name [description]
|
||
* @param {[type]} value [description]
|
||
*/
|
||
set: function(name, value){
|
||
if (isObject(name)) {
|
||
for(var key in name){
|
||
session_data[this.cookie][key] = name[key];
|
||
}
|
||
}else {
|
||
session_data[this.cookie][name] = value;
|
||
}
|
||
},
|
||
/**
|
||
* 移除session
|
||
* @return {[type]} [description]
|
||
*/
|
||
rm: function(name){
|
||
if (name) {
|
||
delete session_data[this.cookie][name];
|
||
}else{
|
||
session_data[this.cookie] = {};
|
||
}
|
||
},
|
||
/**
|
||
* gc
|
||
* @param {[type]} now [description]
|
||
* @param {[type]} timeout [description]
|
||
* @return {[type]} [description]
|
||
*/
|
||
gc: function(now, timeout){
|
||
for(var cookie in session_data){
|
||
var time = session_data[cookie].__ACTIVE_TIME__ || 0;
|
||
if (now - time > timeout) {
|
||
delete session_data[cookie];
|
||
};
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
//解析cookie
|
||
Session.start = function(http){
|
||
if (http.session_cookie) {
|
||
return http.session_cookie;
|
||
};
|
||
var name = C('session_id');
|
||
//是否使用签名
|
||
var secret = C('session_cookieSign');
|
||
var cookie = http.cookie[name];
|
||
if (cookie && secret) {
|
||
cookie = cookieUnsign(cookie, secret);
|
||
};
|
||
var session_cookie = cookie;
|
||
if (!cookie) {
|
||
cookie = uid(32);
|
||
session_cookie = cookie;
|
||
if (secret) {
|
||
cookie = cookieSign(cookie, secret);
|
||
};
|
||
http.setCookie(name, cookie, C('session_options'));
|
||
}
|
||
//将cookie值放到http对象上,方便后续获取
|
||
http.session_cookie = session_cookie;
|
||
|
||
var name = C('session_type') + "Session";
|
||
//session类
|
||
http.session = thinkRequire(name)(http);
|
||
|
||
return cookie;
|
||
}; |