对于想了解ExpresscookieSession和Mongoose:如何使request.session.user成为Mongoose模型?的读者,本文将提供新的信息,并且为您提供关于$Django
对于想了解Express cookieSession和Mongoose:如何使request.session.user成为Mongoose模型?的读者,本文将提供新的信息,并且为您提供关于$Django cookies与session--解决无连接无状态问题, session配置、ASP.Net会话超时检测:Session.IsNewSession和SessionCookie检测是最好的方法吗?、cookie-parser与 express-session、django request.session.session_key获取的值为None的有价值信息。
本文目录一览:- Express cookieSession和Mongoose:如何使request.session.user成为Mongoose模型?
- $Django cookies与session--解决无连接无状态问题, session配置
- ASP.Net会话超时检测:Session.IsNewSession和SessionCookie检测是最好的方法吗?
- cookie-parser与 express-session
- django request.session.session_key获取的值为None
Express cookieSession和Mongoose:如何使request.session.user成为Mongoose模型?
创建新用户帐户后,我创建了newUser,这是一个Mongoose模型实例,如下所示:
_events: Objecterrors: undefinedisNew: falsesave: function () {arguments: nullcaller: null_doc: Object name: ''Joe Smith''...
该对象的实际数据位于 _doc 属性中,尽管存在getter和setter,所以您可以运行:
user.name = ''Jane Doe''
这样就可以了。我跑:
request.session.user = newUser;
将用户保存到会话。到目前为止,一切都很好。
但是,在后续请求中,request.session.user似乎只是_doc中的内容。例如:
name: ''Joe Smith''
很好,但这意味着我无法运行例如 request.session.user.save() 来保存更改。
我可以简单地制作一些中间件来查找与数据关联的用户。但是我想了解更多有关Express和Mongoose在这里做什么的信息。
如何使request.session.user成为Mongoose模型?
更新 :我当前的中间件黑客:
// Use as a middleware on routes which need users// TODO: only needed due to request.session.user being saved weirdlyvar rehydrateUser = function(request, response, next) { if ( request.session.user ) { var hydrated = request.session.user.save if ( ! hydrated ) { console.log(''Rehydrating user...''); models.User.findOne({ somefield: request.session.user.somefield }, function (err, user) { if ( err ) { request.session.error = ''User not found in DB!''; request.redirect(''/''); } else { request.session.user = user; console.log(''Rehydrated user! All repos already being monitored.''); next(); } }) } else { next(); } } else { console.log(''No user in session'') next(); }}
答案1
小编典典Express会话存储为单独的存储,并且对可以在那里存储的内容有限制。它不能存储原型数据(方法)。看起来更像是key<>value
存储。
这样做的原因是会话可以存储在任何地方(很多),例如:进程内存;数据库(mongodb); 重做 等等
因此,一旦在会话对象中放入任何内容并完成请求,express就会获取会话数据,将其解析并像纯对象一样粘贴到会话存储中。默认情况下,它是进程内存,但是如前所述-
可以是任何其他存储。
因此,当下一个http请求发生时,会话中间件将尝试使用请求标头中的cookie(如果使用了)数据来恢复会话,并要求会话存储提供数据。因为它已经被格式化-
它不会有.prototype的东西,但只是数据(object
,array
,string
,number
,和其他简单的东西)。
因此,您需要再次根据该数据创建模型。
您可以通过中间件快速完成。因此,app.configure
在定义后,session
您可以直接执行以下操作:
app.use(function(req, res, next) { if (req.session && req.session.user) { req.session.user = new UserModel(req.session.user); } return next();});
这将检查是否定义了会话以及用户。然后将根据该数据重新创建猫鼬模型。
如此处的注释中所述-您不应在会话中存储用户数据,因为由于责任与数据所有权的划分会导致不一致。因此,仅存储ID
用户,然后使用中间件从数据库加载它。
app.use(function(req, res, next) { if (req.session && req.session.userID) { UserModel.findById(req.session.userID, function(err, user) { if (!err && user) { req.user = user; next(); } else { next(new Error(''Could not restore User from Session.'')); } }); } else { next(); }});
在您可以创建中间件以检查用户是否登录后:
function userRequired(req, res, next) { if (req.user) { next(); } else { next(new Error(''Not Logged In''); }}
并像这样使用它:
app.get(''/items'', userRequired, function(req, res, next) { // will only come here if user is logged in (req.user !== undefined)});
$Django cookies与session--解决无连接无状态问题, session配置
session作用:
会话保持,记住用户的登录状态(WEB网站,分布式架构)
作用(和cookie的区别)
避免了敏感信息保存在客户端,防止客户端修改cookie信息!
- 原理
是服务器产生,发给客户端浏览器,浏览器保存起来,下次发请求,会携带这个键值对到服务器
- Cookie的覆盖:先写了一个键值对key1,v1,后来再写key1,v2, v2会把原来的值覆盖掉
-cookie使用(**********************)
- 写:可以在Jsonresponse,三件套这个对象上写
obj=Jsonresponse({''1'':''2''})
obj.set_cookie(key,value)
return obj
- 取:request.COOKIES#字典
request.COOKIES.get(''key'')
- 删除:
obj.delete_cookie(''name'')
设置cookie
1.普通cookies
obj. set_cookie("tile","111",expires=value,path=''/'' )
2.加盐cookies:保护数据信息
普通cookie是明文传输的,可以直接在客户端直接打开,所以需要 加盐, 解盐之后才能查看
obj. set_signed_cookie(''k'',''v'', salt="111ss")
获取cookie
1、普通
request.COOKIES.get(‘k’)
2、加盐
v= request. get_signed_cookie(''k'', salt=''111ss'')
-cookie的其他属性
set_COOKIES(max_age=10,path=''/index/'')
set_signed_cookie(''k'',''v'',salt="111ss",)
- max_age,失效时间 传一个秒的时间
- expires,失效日期 传一个datatime对象
- path=''/'',可以设置路径,设置路径之后,path=''/index/'',只有访问index的时候,才会携带cookie过来
- domain= ,设置域名下有效domain=''map.baidu.com''
- secure=False, (默认是false,设置成True浏览器将通过HTTPS来回传cookie)
- httponly=True 只能https协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
- 登录认证装饰器,登录之后自动跳转【登陆界面 上一个访问页面】
def login_auth(func):
def inner(request, *args, **kwargs):
# 拿到之前访问的路径
# 这个不行,因为取不到数据部分
# url=request.path
url = request. get_full_path()
if is_login:
res = func(request, *args, **kwargs)
return res
else:
return redirect(''/login/ ?next=%s'' % url)
return inner
-session
-解决cookie不安全的问题,
-存在服务器上的键值对{''随机字符串'':{name:lqz,pwd:123}} #v:字典
-用session必须跟cookie连用
-session使用(****************)
- 设置值
- request.session[''name'']=''lqz''
-如果设置多个,它会以字典的形式存储到session表中的session_data中
- 生成session时:
1 生成随机字符串:dfasfasdfa
2 取数据库存储 【需要django_session表 2条迁移命令】
随机字符串 值 (字典形式) 超时时间
dfasfasdfa {''name'':''lqz'',''age'':18,''sex'':''男''} 超时时间
3 写入浏览器cookie:set_cookie(''sessionid'',''dfasfasdfa'')
-取值
name=request.session[''name'']
- 执行流程:
1 取到cookie的随机字符串:request.COOKIES.get(''sessionid'')
2 session表中根据【随机字符串】查询,查询出session_data这个字典,然后把字典中name返回
-删除值
-删除数据库当前cookie数据
取出cookie,随机字符串,去数据库删除随机字符串是当前值的记录
request.session.delete()
-删除浏览器cookie,又删除数据库
request.session.flush()
-session其他属性
-request.session. setdefault(''k1'',123) # 存在则不设置
-取到随机字符串,浏览器带过来的 cookie的值
print(request.session.session_key)
内部执行了:
request.COOKIES.get(''sessionid'')
-清空过期失效的session
request.session. clear_expired()
-校验sessionid是否存在
request.session. exists("session_key")
session的配置
-不但能放到数据库,还能放到文件中,redis(内存数据库)
SESSION_ENGINE = ''django.contrib.sessions.backends.db'' # 引擎(默认)
2. 缓存Session
SESSION_ENGINE = ''django.contrib.sessions.backends.cache'' # 引擎
SESSION_CACHE_ALIAS = ''default'' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
3. 文件Session
SESSION_ENGINE = ''django.contrib.sessions.backends.file'' # 引擎
SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
4. 缓存+数据库
SESSION_ENGINE = ''django.contrib.sessions.backends.cached_db'' # 引擎
5. 加密Cookie Session
SESSION_ENGINE = ''django.contrib.sessions.backends.signed_cookies'' # 引擎
其他公用设置项:
SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
#如果设置 True,在30分钟期间有请求服务端,就不会过期!(为什么逛一晚上淘宝,也不会登出,但是不浏览器不刷新了就会自动登出)
ASP.Net会话超时检测:Session.IsNewSession和SessionCookie检测是最好的方法吗?
在页面加载之前,我需要确定这是否是超时情况,如果是 – 重定向到timeout.aspx.
下面的文章指定如果IsNewSession为true,并且存在sessionID cookie – 那么您有超时情况.
然而,在我的测试中,我遇到了我超时并尝试重新登录并且IsNewSession等于true并且sessionId cookie仍然闲置(因为它保留整个浏览器会话)的情况,因此它说我已经定时当我只是想重新登录时再次出现.
有没有更好的方法来做这一切?
技术描述为here和here.
在我的’global.asax’文件中,我有:
void Application_PreRequestHandlerExecute(object sender,EventArgs e) { // Check if session state is enabled in web.config if (Context.Session == null) return; if (Session["user"] == null) { if (Session.IsNewSession) { HttpCookie sessionCookie = Request.Cookies["ASP.NET_SessionId"]; if ((null != sessionCookie) && !string.IsNullOrEmpty(sessionCookie.Value)) { /* Session Timeout! */ FormsAuthentication.SignOut(); //just in case not done yet Session.Abandon(); Response.Redirect("timeout.aspx"); } else { // Cookie didn't exist - must be a brand new login return; } } else { // If there is no session data and the session is not new then it must be the postback of the login screen. if ((HttpContext.Current.Request.Path.ToLower().LastIndexOf("/login.aspx") >= 0) && (Request.HttpMethod == "POST")) { return; } } } }
解决方法
您的问题是,由于会话数据已经消失,您只需要进行新请求即可创建新会话,并且进入的请求会携带会话ID cookie(表示之前已登录).
有两种方法.
曲奇饼:
首先,在您的登录页面中,您可以创建一个指示用户登录状态的附加cookie.当用户手动注销时,cookie值被修改以指示注销.会话超时后的请求除了具有IsNewSession true之外还将具有登录状态cookie,其显示用户仍然登录,从而指示用户未手动选择退出.
数据库:
第二种方法是将sessionID存储在DB表中以及登录状态.登录成功后,将sessionID输入LoggedOnSessions表.当用户手动注销时,从表中删除sessionID.因此,您的超时检测可以包括查找表中的会话ID(如果存在超时)(此时您应该也可以删除ID).
出于清洁目的,您应该包括一个到期日期时间字段,其设置的时间比任何实际登录时间(例如一周)长得多.定期(例如,每周)删除表中已过期的条目.
我的偏好是数据库方法我讨厌设置cookie,因为它让我觉得每次请求都会发送cookie但很少需要.
cookie-parser与 express-session
1. cookie-parser
1.1 cookie的执行原理:当客户端访问服务器的时候(服务运用了cookie),则服务器会生成一份cookie传输给客户端,客户端会自动把cookie保存起来;以后客户端每次访问服务器,都会自动的携带着这份cookie。
1.2 cookie的特点:
(1)保存到客户端,容易被篡改(删除、禁用)
(2)保存的数据量有限的
(3)简单易懂好用
1.3cooke的使用:
(1)安装:npm i cookie-parser
(2)使用:
案例:
先引用:var cookieParser = require('cookie-parser');
app.use(cookieParser());//使用cookie-parser
生成cookie:
//设置cookie
//在响应的时候,生成一份cookie
// res.cookie('xxcode',"abc");
取出cookie:
console.log(req.cookies);
加密cookie:
var cookieParser = require('cookie-parser');
app.use(cookieParser("xiaoxuesheng"));//签名 (加密) 指定秘钥 "xiaoxuesheng"
//使用cookie
//加密存储
res.cookie("mycode","abc",{
signed:true //加密
})
//取出cookie
2. express-session
session是一种特殊的cookie。cookie是保存在客户端的,而session是保存在服务端。
当客户端第一次请求服务器的时候,服务器生成一份session保存在服务端,将该数据(session)的id以cookie的形式传递给客户端;以后的每次请求,浏览器都会自动的携带cookie来访问服务器(session数据id)。
2.1 安装:npm i express-session
2.2 使用:
//引入session中间件
let expressSession=require("express-session")
//使用session中间件
app.use(expressSession({
resave:true,//每次是否都刷新存储器
saveUninitialized:true,
secret:"xiaoxuesheng" //秘钥
}))
代码示例:
使用session存储数据:
//将数据存储到session中
req.session.yourcode='xyz';
取出session数据:
//取出存储的session
console.log(req.session);
2.2 cookie 与session的区别:
(1)cookie是保存在客户端的
(2)session是保存在服务器端的
(3)session会更加的安全可靠
django request.session.session_key获取的值为None
if not request.session.session_key:
request.session.create()
session_id = request.session.session_key
SessionStore.create()用于创建新会话(即未从会话存储加载的会话session_key=None)。
save()用于保存现有会话(即从会话存储加载的会话)。
调用save()新会话也可能有效,但产生session_key与现有会话冲突的可能性很小。create() 调用save()和循环,直到session_key生成未使用的。
关于Express cookieSession和Mongoose:如何使request.session.user成为Mongoose模型?的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于$Django cookies与session--解决无连接无状态问题, session配置、ASP.Net会话超时检测:Session.IsNewSession和SessionCookie检测是最好的方法吗?、cookie-parser与 express-session、django request.session.session_key获取的值为None等相关内容,可以在本站寻找。
本文标签: