GVKun编程网logo

Express cookieSession和Mongoose:如何使request.session.user成为Mongoose模型?

12

对于想了解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模型?

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的东西,但只是数据(objectarraystringnumber,和其他简单的东西)。

因此,您需要再次根据该数据创建模型。
您可以通过中间件快速完成。因此,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配置

$Django cookies与session--解决无连接无状态问题, session配置

session作用:

会话保持,记住用户的登录状态(WEB网站,分布式架构)

作用(和cookie的区别)

避免了敏感信息保存在客户端,防止客户端修改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()
    is_login = request.COOKIES.get(''is_login'')
    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(内存数据库)
 
1. 数据库Session
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过期(默认)
SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
#如果你设置了session的过期时间 30分钟后,这个参数是False30分钟过后,session准时失效
#如果设置 True,在30分钟期间有请求服务端,就不会过期!(为什么逛一晚上淘宝,也不会登出,但是不浏览器不刷新了就会自动登出)

ASP.Net会话超时检测:Session.IsNewSession和SessionCookie检测是最好的方法吗?

ASP.Net会话超时检测:Session.IsNewSession和SessionCookie检测是最好的方法吗?

当我的ASP.Net会话超时(并形成身份验证)并尝试点击页面时,我会自动重定向到我的默认login.aspx页面.

在页面加载之前,我需要确定这是否是超时情况,如果是 – 重定向到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

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等相关内容,可以在本站寻找。

本文标签: