跟我一起学NodeJs之登录验证

login.jpg

前面我们讲了数据库的操作,已经可以轻松实现增删改查,接下来,就是服务端开发中的一个重点,就是登录验证,本篇文章由浅入深介绍登录验证中cookie,session,redis的作用。开始吧

登录

cookie

首先我么需要了解cookie。以如何查看cookie,客户端如何操作cookie

  • 存储在浏览器中的一段字符串(5kb)
  • 跨域不共享
  • 可以发送给server端
server端操作cookie
  • 查看
  • 修改
  • 登录验证
  1. 解析cookie
//解析cookie
req.cookie = {}
const cookieString = req.headers.cookie || ''
cookieString.split(';').forEach(item => {
    if(!item) {
        return
    }
    const arr = item.split('=')
    const key = arr[0].trim()//trim()去掉前后空格
    const val = arr[1].trim()
    req.cookie[key] = val
})

上面的代码将‘k1=v1; k2=v2;’这样的字符串变为对象,我们可以直接从req.cookie中获取。

  1. 登录时设置cookie
//定义过期时间函数
const getCookieExpires = () => {
    const d = new Date()
    d.setTime(d.getTime() + (24 * 60 * 60 * 1000))
    return d.toGMTString()
}

res.setHeader('Set-Cookie', `username=${data.username}; path=/; httpOnly; expires=${getCookieExpires()}`)

需要注意:

  • pathcookie的生效路径,我们一般要设置为项目的根目录,才能在项目中所有路径中生效;
  • httpOnly限制只能在服务端修改cookie,防止用户客户端修改cookie;
  • expires为设置过期时间

如上,我们已经可以利用cookie来做登录验证,但上面的方法还是存在着一些问题,他会把一些关键信息暴露在cookie中,在客户端可以被查看,这是不安全的,所以,我们下面将使用session来讲重要的信息存储在session中,因为session是存在内存中的,其容量也比cookie大的多,所以使用session将是一个很棒的解决方案

Session

使用session后,我们的登录信息的处理机制要变一变,待会会做出下面的修改

    // 解析session
let needSetCookie = false
let userId = req.cookie.userid
if (userId) {
    if (!SESSION_DATA[userId]) {
        SESSION_DATA[userId] = {}
    } 
} else {
    needSetCookie = true
    userId = `${Date.now()}_${Math.random()}`
    SESSION_DATA[userId] = {}
}
req.session = SESSION_DATA[userId]

我们会根据当前访问接口中,有无需要设置cookie来做出判断

userResult.then(userData => {
    if(needSetCookie) {
        res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
    }
    res.end(
        JSON.stringify(userData)
    )
})

这样,我们在controller中就不需要设置cookie了,只需要在登录接口中,设置session即可

if(data.username) {
    // 设置session
    req.session.username = data.username
    req.session.realname = data.realname
    return new SuccessModel()
}

接下来捋一捋代码吧,看看用session怎么做登录验证
上面我们使用了session做登录验证,并把一些重要信息存于内存中但这样会面临如下问题

  • session存储于一个js变量中。
  • 数据量大,内存爆了怎么办?
  • 线上是多进程的,且进程间内存不共享。我们的session将不能保证准确访问

于是,我们将引入下一个概念--Redis

Radis

  1. web Server中最常用的内存数据库
  2. 相比于mysql,访问速度更快(因为mysql基于硬盘,redis基于内存)
  3. 成本高,可存储的数据量 小

在项目中,我们采用mysql和redis结合使用的方式

  • 将webServer和redis拆分为两个单独的服务
  • 双方都是独立的,都是可扩展的
为什么Session适合存储于redis中?
  • session访问频繁,对性能要求极高
  • session可以不用考虑断点丢失的问题(这是内存的硬伤)
  • session中数据量不会很大(相比于mysql中的数据)
为什么网站数据不适合使用redis?
  • 操作频率不是太高(相对于session操作)
  • 断电不能丢失,必须保留
  • 数据量太大,内存成本太高
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 背景在HTTP协议的定义中,采用了一种机制来记录客户端和服务器端交互的信息,这种机制被称为cookie,cooki...
    时芥蓝阅读 2,485评论 1 17
  • 注:本文转载自前端大全 背景 在HTTP协议的定义中,采用了一种机制来记录客户端和服务器端交互的信息,这种机制被称...
    楠小忎阅读 753评论 0 0
  • 普遍的回答: cookie和session的区别:cookie存储在客户端,session存储在服务器 token...
    SMEB_阅读 7,743评论 0 14
  • 丁玲著 7.3-7.4 个人感觉和《韦护》《莎菲女士的日记》风格转变挺大。我联系了赵树理《小二黑结婚》的艺术特色,...
    嗡的阅读小马甲阅读 763评论 0 1
  • . 从功能上 - 原生词缀 ~ 只能与粘附词根结合 ~ 它都是与粘附词根整机输入的,不能分离出来 ~ 有...
    享悦moonlight阅读 528评论 0 0

友情链接更多精彩内容