【前端升全栈】五分钟了解项目开发的登录部分(上)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 注册的话其实就像是新增博客,没啥难度,更何况现在都短信注册或者微信扫码等等,没有太大意义。

1.登录开始

注册的话其实就像是新增博客,没啥难度,更何况现在都短信注册或者微信扫码等等,没有太大意义。

登录:

  1. 核心:登录校验&登录信息存储
  2. 为何只讲登录,不讲注册?

Mysql 是硬盘数据库,redis 是内存数据库。

目录:

  1. cookie和session
  2. session写入 redis
  3. 开发登录功能,和前端联调(用到 nainy后向代THP

2.cookie简介

主要了解什么?

  1. 什么是cookie
  2. javascript操作cookie ,浏览器中查看cookie
  3. server端操作cookie ,实现登录验证

跨域不共享就是说淘宝和百度的 cookie 是不一样的,各自有各自的 cookie

什么是cookie?

  1. 存储在浏览器的一段字符串(最大5kb )
  2. 跨域不共享
  3. 格式如k1=v1; k2=v2; k3=v3;因此可以存储结构化数据

请求域的 cookie 就是说请求什么如请求百度的 xx 文件就是请求百度的 cookie(不管是在什么页面请求,主要看的是请求的是谁而不是看在什么页面)。

cookie:

  1. 每次发送http请求,会将请求域的cookie一起发送给server
  2. server可以修改cookie并返回给浏览器
  3. 浏览器中也可以通过javascript修改cookie(有限制)

所谓有限制就是服务端返回后将其锁死不愿意让客户端去修改(为了安全)。

客户端JavaScript操作cookie:

  • 客户端查看cookie ,三种方式
  • javascript查看、修改cookie(有限制)

document.cookie 查看 cookie ,添加的话其实是采用累加的方式 document.cookie = ‘要添加的键值对’(就直接加在 cookie 的后面)。查看 application 下面有 cookie 的详细信息,其中的 path 如果是 / 代表的是根路径,就是说不管我们 url 路径多复杂,都可以使用该 cookie 。

2345_image_file_copy_486.jpg

3.cookie用于登录验证

server端Nodejs操作cookie:

  1. 查看cookie
  2. 修改cookie
  3. 实现登录验证

回到 app.js,我们来解析 cookie,查看请求的 headers 就可以拿到 cookie,没有就返回空字符串,需要注意的是由于返回的是字符串,使用不是很方便,所以这里还需要解析成对象。 通过split先拆分;拿到每一组,再通过=拆分拿到key和value。我们尝试一下,要是想删除 cookie 的话可以前往 application删。

   回到 user.js 我们来规定一下如果 cookie 有 username 就是登 录成功,否则就失败,定义一个测试的路径,记得我们自己所有路由都改成了需要返回 promise ,如果没有封装 promise 可以利用 Promise.resolve 封装一些。那么后端如何修改 cookie ,通过 res 的 setHeader 方法设置 Set-Cookie 和 path=/(如此则所有的网站网页的路由都会生效)。说一下,首先是在 app.js 解析 cookie 方便各地使用。

/解析cookie
req.cookie=//定文一个存放cookie的对象
const cookiestr = req.headers.cookie |l"//拿到cookie字符串或者空字符串cookiestr.split('; ').forEach(item => {//通过;分割出一组cookie
if (litem){
return
const arr = item.split('=')1/通过-分割每一组cookie的key和vaLueconst key = arr[o]
const value = arr[1]req.cookie[key] = value))
console.log(req.cookie)//到此各地皆可以使用req.cookie来获取已经解析完成的cookie了

接着是在 router 里面对是否登录进行验证(主要是查看是否 有 username 存在,注意有可能会因为 username 被当成字符串导致判断失败),这一步可以手动加 cookie,对测试进行验证.

if (method === 'GET' &8 req.path === '/api/user/login-test') {
  if (req.cookie.username){//通过查看cookie里面有没有username这个key判断是否登录成功(注意有个 
      return Promise.resolve(new successMode1('登录成功'))
return Promise.resolve(new ErrorModel(尚未登录'))
}

 在上面的验证可以生效后我们就可以使用了,在用户登录的 时候同时设置好 cookie,且设置为根路径方便 3000 端口下的都可以访问到,这一步的话由于改成 GET,需要在路径加上密码用户名,访问后就设置好了 cookie,再回 test 测试是否可以成功验证.

2345_image_file_copy_487.jpg

4.cookie做限制

然而目前还是有一个问题,就是 js 可以很轻易的设置document.cookie 来覆盖之前的 cookie 伪造身份。 那么怎么去限制呢?很简单,后端设置 cookie 的时候加多一个 httpOnly 即只允许通过服务端修改不允许通过客户端修改。这个时候 HTTP 就会多一个√,且不仅仅是看不见也不 能修改(指的是客户端)。

   按理说不应该被修改,我们最后发现其实是被改的那个前面被加了个空格,这是因为新增cookie 前面都会有这个空格(如果前面有值)很简单,只需要 trim ()去掉几空格就行。 现在在客户端修改的话当然改什么就会在 cookie 出现什么,只不过被锁死的还是锁死,无法被覆盖。 另外,也不应该一直存着 cookie ,应该有个过期时间比较合适,我们定义一个 getCookieExpires 函数,获取当前时间, 并且再加上 24 个小时,返回的话改成 toGMTString 时间格式。 然后就可以回去设置 cookie 的 expire 即过期时间直接等于这个函数就行。

2345_image_file_copy_488.jpg

5.session介绍

将一下 cookie 的问题:危险的个人信息,极小的可存空间。session 是储存登录/会话信息的统称,通过 cookie 里面的 id去服务端对应一个具体的信息。

session:

  1. 上—节的问题:会暴露username ,很危险
  2. 如何解决:cookie中存储userid , server 端对应username
  3. 解决方案:session ,即server端存储用户信息

2345_image_file_copy_489.jpg

session

如上图,浏览器中 cookie 提供了 id,传到服务端,服务端可 以有 xxx 对应什么内容,yyy 对应什么内容的约定等等。 回到 app.js 定义一个 SESSION_DATA 的常量,在解析 cookie 后就可以来解析这个 session,判断 cookie 是否有 userId,有 则判断常量里面是否存在 userId,如果不存在则将常量的userId 属性设置为空对象,再赋值给我们的 req.session。如果 cookie 没有 userId 我们就随便定义一个时间戳再去赋值给常量里面的 userId 最后再赋值给我们的 req.session。

   这个还是加多一个判断,定义一个 needSetCookie 状态,看看是否需要设置 cookie(cookie 不存在 userId 的时候就要), 实现在 blogs 和 users 的路由,把 userId 设置到 cookie 上。 那么怎么使用呢?这个就需要到登录那里原本设置cookie的可以去掉了,改为设置 session,同时验证登录的时候也改成判断 session。

2345_image_file_copy_490.jpg

6.session演示

   上面有报错啊,有两个问题,第一个就是获取 cookie 时间的函数没有拷贝过来,第二个就是状态和 userId 后面都会改不能定义成常量,改成 let ! 注意 userId 的话是不管访问哪个路由都会有(因为路由们都会经过那个 serverHandle 共同的函数)。当然并不是每次刷新都会设置 cookie ,第一次就会,之后判断存在 userId 就不走设置 cookie 的分支了。所以我来捋一下,首先我们访问的是 login-test ,先走的是解析 session ,判断不存在 userId 且定义了 userId (第一次才会,之直接走给 req 赋值 session ),搞定去 login-test 路由,判断当前不存在 username 所以是未登录,回到 users 总路由设置 cookie 。接下来走 login 路由,先判断 session 存在了,赋值给 req ,走 login 路由,填充 session ,完成回到 user 总路由发送内容。再走一次 login-test ,判断 session 中有这个username 所以判断登录成功,自始至终只有 userId 暴露在外,具体拿到这个 userId 怎么处理是只有服务端才能看到。

总计:

  • 知道session解决什么问题;
  • 如何实现session

所以说 cookie userId 只是为了给我这个专属的 userId 开辟 一个独特的存放 session 的空间,而 session 则是保存了实际的信息。


7.从session到Redis

当前写的 session 还是有问题的。目前本地的 node.js 当然是只有一个进程,但是上线多进程(甚至是多机房什么的)可能导致我们呃,第一次登录到其中一个进程,第二次登录却是另一个进程而失败。

session的问题:

  1. 目前session直接是js 变量,放在nodejs进程内存中
  2. 第一,进程内存有限,访问量过大,内存暴增怎么办?
  3. 第二,正式线上运行是多进程,进程之间内存无法共享

如图就是进程的内存模型,其中 0x1000 是起始地址,0x8000 是结束地址,stack 储存的是程序运行的基础变量(js 的基础 变量),heap 存的是程序运行的引用变量(js 的数组对象什么的,session 也放在这里),存的越多,占的就越多(越高) 如果上下接起来那就崩了。

2345_image_file_copy_491.jpg

进程内存模型

 操作系统会限制一个进程的最大可用内存(大概是 3G),而 session 是存在一个 node.js 进程的,不可能无限储存,一旦存的太多,撑爆 node.js 进程就 GG

2345_image_file_copy_492.jpg

上线的时候每个 node.js 程序都是分多个进程来跑的,因为 单个进程占的内存有限,也浪费其它的内存。而且多核的处 理器可以处理多个进程。这是符合内存与 cpu 的实际情况。 当然进程之间是不能互相访问的,不能共享数据什么的(你 个 QQ 进程总不能去访问我微信进程的数据吧)。回到 node.js,其实每次访问的进程是不一定的(PM2 分配进程, 都挤一个迟早升天),这就导致我在其中一个进程有数据, 到另一个就没有数据了。

2345_image_file_copy_493.jpg

存放内存中意味着读取很快但是也比较昂贵,空间少,一断电就没了(易丢失)

解决方案Redis:

  1. web server最常用的缓存数据库,数据存放在内存中
  2. 相比于mysql,访问速度快(内存和硬盘不是一个数量级的)
  3. 但是成本更高,可存储的数据量更小(内存的硬伤)

 也就是说 redis(内存数据库)和 mysql(硬盘数据库)都是储存数据的;

2345_image_file_copy_494.jpg

解决方案Redis

解决方案Redis:

  • 将web server和redis 拆分为两个单独的服务
  • 双方都是独立的,都是可扩展的(例如都扩展成集群)
  • (包括mysql ,也是一个单独的服务,也可扩展)

解决问题就是将session存放到redis中就行(之前是存在web server)。而既然分开了,redis 储存多少就不管 node.js 进程的事情了(因为分开了啊,变成两个东西),再说访问,因 为就是这一个 redis,不管谁访问还是访问这一个,也就一份数据,不管是哪个进程访问都给一样的数据。就像是一个独立的仓库。就算是太多了,redis 也可以拆分成集群/机房什么的,不需要我们关心。不考虑丢失数据的意思是重新登录即可。

为何session适合用Redis?

  1. session访问频繁,对性能要求极高
  2. session可不考虑断电丢失数据的问题(内存的硬伤)
  3. session数据量不会太大(相比于mysql 中存储的数据)
  4. 为何网站数据不适合使用Redis?
  • 操作频率不是太高(相比于session操作)
  • 断电不能丢失,必须保留
  • 数据量太大,内存成本太高
相关文章
|
3月前
|
存储 JSON 前端开发
node使用token来实现前端验证码和登录功能详细流程[供参考]=‘很值得‘
本文介绍了在Node.js中使用token实现前端验证码和登录功能的详细流程,包括生成验证码、账号密码验证以及token验证和过期处理。
67 0
node使用token来实现前端验证码和登录功能详细流程[供参考]=‘很值得‘
|
4月前
|
前端开发 JavaScript 应用服务中间件
【uniapp】谷歌授权登录,前端uniapp直调(含源码)
本文介绍如何在uniapp项目中实现谷歌授权登录,无需后端参与。文章分为三部分:1)谷歌授权登录流程,详细说明从用户点击登录到获取用户信息的整个过程;2)谷歌开发者控制台配置,包括创建项目、配置同意屏幕及OAuth客户端ID等步骤;3)uniapp前端实操,提供具体代码示例,展示如何获取授权码并用其交换访问令牌,最终获取用户信息
213 2
【uniapp】谷歌授权登录,前端uniapp直调(含源码)
|
5月前
|
存储 开发框架 前端开发
循序渐进VUE+Element 前端应用开发(31)--- 系统的日志管理,包括登录日志、接口访问日志、实体变化历史日志
循序渐进VUE+Element 前端应用开发(31)--- 系统的日志管理,包括登录日志、接口访问日志、实体变化历史日志
|
6月前
|
存储 前端开发 搜索推荐
Web前端网站(一) - 登录页面及账号密码验证
页面背景动态是烟花和文字特效与缓缓下落的雪花相结合,在登录表单的旁边还有五个白色光圈以不规则的方式环绕,当鼠标靠近时,会发出彩色的光芒~~~
109 1
Web前端网站(一) - 登录页面及账号密码验证
|
5月前
|
存储 开发框架 前端开发
循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理
循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理
|
6月前
|
前端开发 JavaScript 程序员
程序员必知:完成登录与注册页面的前端
程序员必知:完成登录与注册页面的前端
26 0
|
7月前
|
前端开发 JavaScript Java
前端和Java验签以太坊钱包签名实现中心化登录
前端和Java验签以太坊钱包签名实现中心化登录
1040 8
|
7月前
|
存储 前端开发 JavaScript
前端笔记_OAuth规则机制下实现个人站点接入qq三方登录
前端笔记_OAuth规则机制下实现个人站点接入qq三方登录
93 1
|
7月前
|
前端开发 安全 数据安全/隐私保护
详解前端登录流程:实现原理与最佳实践
详解前端登录流程:实现原理与最佳实践
|
7月前
|
监控 前端开发 安全
【专栏】介绍了前端工程师如何掌握SSH命令,包括SSH协议的基础知识、命令行操作如登录、文件传输、目录管理和进程管理
【4月更文挑战第29天】本文介绍了前端工程师如何掌握SSH命令,包括SSH协议的基础知识、命令行操作如登录、文件传输、目录管理和进程管理。在前端开发中,SSH用于部署项目、协同后端开发及服务器监控。文章还强调了使用密钥认证、配置别名及安全注意事项,并提醒开发者面对问题时如何解决。学习和熟练运用SSH是前端工程师适应复杂项目需求的关键。
142 0

热门文章

最新文章