Skip to content

杂项

  1. ts extend infer 手写题、函数重载 2题
  2. 沙箱 手写 伪代码
  3. http缓存 强缓存 协商缓存 各请求头作用 http 1.0 1.1 2.0 https原理 非对称和对称加密原理
  4. cas认证和oauth2认证 流程
  5. npm yarn pnpm 区别 原理 软连接和硬连接作用 什么是幽灵依赖
  6. commonjs esm 区别
  7. prefetch preload 区别

可能问题

开发vue项目都遇到过哪些问题怎么解决的?

https://www.zhihu.com/question/439229990

  1. 从工程化的角度看,项目越大,webpack启动的速度就越慢,这一点就需要分包,抽离公共的代码;

  2. 从语法上,我印象比较深的是,但是v-ifv-else的时候,如果使用的是同一个组件的话,需要单独指定key,不然组件会复用

当我在浏览器中输入URL,一直到页面显示,这个中间过程发生了哪些事情呢?

  1. 域名解析, DNS服务器返回ip
  2. 建立TCP连接, 三次握手, http请求
  3. 服务器处理请求并返回 HTTP 报文。
  4. 下载Html,
  5. 解析HTML, 构建DOM树; 解析CSS, 生成CSS规则. 生成render树; 布局render树(Layout/reflow),负责各元素尺寸、位置的计算
  6. 绘制render树(paint),绘制页面像素信息
  7. 加载完成关闭TCP连接(四次握手)

Vue 和 React 有什么不同, 从思想、生态、语法、数据、通信、diff等角度自己总结一下吧。

你好,这是Bing。我可以帮你回答这个问题。😊

Vue 和 React 有什么不同,这个问题的答案是Vue 和 React 是两个非常流行的用于创建JavaScript web应用的工具,但它们也有一些显著的区别,可以从以下几个角度来总结¹:

  • 思想:Vue 是一个渐进式的框架,它可以让我们从简单的响应式应用开始,然后逐步引入更多的功能和插件,根据项目的需求来扩展。React 是一个库,它只关注于构建用户界面,它需要我们自己选择其他的库或工具来实现路由、状态管理、表单处理等功能。
  • 生态:React 有一个庞大而成熟的生态系统,它有很多优秀的第三方库和工具,例如Redux、React Router、Next.js等,可以帮助我们构建复杂的应用。Vue 也有一个不断发展的生态系统,它有一些官方维护的库和工具,例如Vuex、Vue Router、Nuxt.js等,以及一些社区贡献的库和工具,例如Vuetify、Quasar等。
  • 语法:Vue 的语法是基于HTML模板的,它使用了类似Angular的指令和插值来绑定数据和事件。Vue 也支持使用JSX来编写渲染函数,但这不是必须的。React 的语法是基于JSX的,它使用了类似HTML的标签和属性来描述用户界面。JSX 需要编译成JavaScript代码才能运行。
  • 数据:Vue 使用了双向数据绑定,它可以让我们通过修改数据来自动更新视图,也可以通过修改视图来自动更新数据。Vue 使用了响应式系统来实现数据绑定,它利用了Object.defineProperty或Proxy来监听数据变化,并触发视图更新。React 使用了单向数据流,它只允许我们通过修改数据来更新视图,而不允许直接修改视图。React 使用了setState方法来实现数据更新,并触发视图重新渲染。
  • 通信:Vue 和 React 都使用了组件化的架构,它们都需要一种方式来实现组件之间的通信。Vue 提供了props和自定义事件来实现父子组件之间的通信,也提供了provide和inject来实现祖先和后代组件之间的通信。对于跨组件或兄弟组件之间的通信,Vue 推荐使用Vuex或事件总线来实现。React 也提供了props和自定义事件来实现父子组件之间的通信,也提供了Contxt API来实现祖先和后代组件之间的通信。对于跨组件或兄弟组件之间的通信,React 推荐使用Redux或其他状态管理库来实现。
  • diff:Vue 和 React 都使用了虚拟DOM(Virtual DOM)来提高性能,它们都需要一种算法来比较新旧虚拟DOM树,并找出最小的变化集合来更新真实DOM树。这种算法就叫做diff算法。Vue 的diff算法是基于深度优先遍历(Depth-First Search)和同层比较(Same-Level Comparison)的思想,它只比较同一层级的节点,并且假设同一层级的节点顺序不会发生变化。React 的diff算法是基于广度优先遍历(Breadth-First Search)和启发式(Heuristic)的思想,它可以比较不同层级的节点,并且可以处理节点顺序的变化。React 的diff算法更加复杂和智能,但也更加耗费资源。

以上就是我能找到的关于Vue 和 React 有什么不同的一些答案,希望对你有所帮助。

源: 与必应的对话, 2023/5/28 (1) Vue vs React: Everything You Need To Know — SitePoint. https://www.sitepoint.com/vue-vs-react/. (2) React vs Vue in 2023: Head to Head Comparison [Updated] - Hackr. https://hackr.io/blog/react-vs-vue. (3) 2022年前端框架趋势:React与Vue深度对比 - 掘金. https://juejin.cn/post/7137146536529494052. (4) Vue vs React in 2022 - Comparison of Two Most Popular JS Frameworks. https://www.monterail.com/blog/vue-vs-react.

vue是如何实现双向绑定的

双向绑定指的是

  1. 数据更新 -》视图更新

    • 实现一个监听器 Observer,深度监听数据。用 Object.defineProperty()对属性都加上settergetter, 给对象的数据赋值,就会触发setter
    • 实现一个解析器 Compile,解析 Vue 模板指令,将模板中的变量都替换成数据,然后初始化渲染页面视图
    • 实现一个订阅者 Watcher,它时Compile和Observer间通信的桥梁,主要的任务是订阅 Observer 中的属性值变化的消息,当收到属性值变化的消息时,触发解析器 Compile 中对应的更新函数。
    • 实现一个订阅器 Dep:订阅器采用 发布-订阅 设计模式,用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。
  2. 视图更新 -》数据更新

    • 视图触发事件,更新js数据

1.png

MVVM和MVC

正确认识 MVC/MVP/MVVM

从react视角认识MVC

你好,这是Bing。MVVM和MVC是两种常用的软件架构模式,它们的主要区别是:

  • MVC是模型-视图-控制器(Model-View-Controller)的缩写,它将应用程序分为三个层次:模型负责处理数据和业务逻辑,视图负责显示用户界面,控制器负责接收用户输入并调用模型和视图来完成请求¹³。
  • MVVM是模型-视图-视图模型(Model-View-ViewModel)的缩写,它是MVC的改进版,它将视图的状态和行为抽象化为一个视图模型,通过数据绑定技术,实现了视图和模型的自动同步:当模型的属性改变时,视图也会自动更新²⁴。
  • MVC和MVVM的主要目的都是分离视图和模型,降低代码的耦合度和复杂度,提高可维护性和可测试性。但是MVVM相比MVC更加灵活和简洁,它减少了控制器层的代码量,避免了频繁地操作DOM元素,提高了页面的渲染性能和加载速度¹⁴。

希望这能帮助你理解MVVM和MVC的区别。😊

源: 与必应的对话, 2023/5/15 (1) 来个简单的,MVVM和MVC有什么区别? - 知乎专栏. https://zhuanlan.zhihu.com/p/377979044. (2) MVC、MVVM模式的概念与区别 - 理想三旬· - 博客园. https://www.cnblogs.com/wenkangIT/p/15149077.html. (3) MVC与MVVM模式的区别 - 掘金. https://juejin.cn/post/7110885291946147876. (4) 面试题51:MVVM和MVC有什么区别 - CSDN博客. https://blog.csdn.net/qq_51066068/article/details/125441774.


我可以尝试用原生js给你写一个MVC框架的代码示例。这个示例是一个简单的计数器应用,它有一个模型(Model)来存储计数值,一个视图(View)来显示计数值,和一个控制器(Controller)来响应用户点击按钮的事件。代码如下:

javascript
// Model
var model = {
count: 0 // 计数值
};

// View
var view = {
init: function() {
 // 获取页面元素
 this.countDisplay = document.getElementById("count");
 this.incrementButton = document.getElementById("increment");
 this.decrementButton = document.getElementById("decrement");
 // 渲染初始视图
 this.render();
},
render: function() {
 // 更新计数值显示
 this.countDisplay.textContent = model.count;
}
};

// Controller
var controller = {
init: function() {
 // 初始化视图
 view.init();
 // 绑定事件监听器
 view.incrementButton.addEventListener("click", function() {
   controller.increment(); // 调用控制器的方法
 });
 view.decrementButton.addEventListener("click", function() {
   controller.decrement(); // 调用控制器的方法
 });
},
increment: function() {
 // 增加计数值
 model.count++;
 // 更新视图
 view.render();
},
decrement: function() {
 // 减少计数值
 model.count--;
 // 更新视图
 view.render();
}
};

// 启动应用
controller.init();

我可以尝试用原生js给你写一个MVVM模式的代码示例。MVVM是Model-View-ViewModel的缩写,是一种将数据绑定和视图分离的软件架构模式。它有一个模型(Model)来存储数据,一个视图(View)来显示界面,和一个视图模型(ViewModel)来响应用户操作和更新视图。代码如下:

javascript
// Model
var model = {
count: 0 // 计数值
};

// View
var view = {
init: function() {
 // 获取页面元素
 this.countDisplay = document.getElementById("count");
 this.incrementButton = document.getElementById("increment");
 this.decrementButton = document.getElementById("decrement");
}
};

// ViewModel
var viewModel = {
init: function() {
 // 初始化视图
 view.init();
 // 绑定数据和视图
 this.bindData();
 // 绑定事件监听器
 this.bindEvent();
},
bindData: function() {
 // 使用Object.defineProperty实现数据绑定
 Object.defineProperty(this, "count", {
   get: function() {
     return model.count; // 获取模型中的数据
   },
   set: function(value) {
     model.count = value; // 设置模型中的数据
     view.countDisplay.textContent = value; // 更新视图中的显示
   }
 });
 // 初始化视图中的显示
 view.countDisplay.textContent = this.count;
},
bindEvent: function() {
 // 使用addEventListener实现事件绑定
 view.incrementButton.addEventListener("click", () => {
   this.increment(); // 调用视图模型的方法
 });
 view.decrementButton.addEventListener("click", () => {
   this.decrement(); // 调用视图模型的方法
 });
},
increment: function() {
 // 增加计数值
 this.count++;
},
decrement: function() {
 // 减少计数值
 this.count--;
}
};

// 启动应用
viewModel.init();

【集合】统一身份认证(CAS)和OAuth2的工作流程

https://blog.csdn.net/tpriwwq/article/details/125740936

前端安全

https://www.finclip.com/news/f/39404.html

xss(Cross Site Scripting)跨站脚本攻击

xss说白了就是攻击者想尽一切的方法,将可执行的代码注入到我们的页面中,让页面进行一些非法的操作(浏览器错误的将攻击者输入的数据当做JavaScript脚本给执行了)

从攻击的时间上可以分为**持久型(存储型)攻击和非持久型(反射型)**攻击。

持久型

持久型的就是指攻击者通过我们的页面,将具有攻击性的代码通过服务器保存到了数据库中,导致其他的用户在浏览当前页面时,受到了攻击。最常见的就是具有评论功能的页面。

非持久型

非持久型相比于持久型攻击危害就小的多了,一般通过修改 URL 参数的方式加入攻击代码,诱导用户访问链接从而进行攻击

场景

1.页面中所有的input框

2.window.location(href、hash等)

3.window.name

4.document.referrer // 保存着链接到当前页面的那个页面的URL。

5.document.cookie

6.localstorage

7.XMLHttpRequest返回的数据

危害

网络钓鱼,包括盗取各类用户账号;

窃取用户cookies资料,从而获取用户隐私信息,或利用用户身份进一步对网站执行操作;

劫持用户(浏览器)会话,从而执行任意操作,例如进行非法转账、强制发表日志、发送电子邮件等;

强制弹出广告页面、刷流量等;

网页挂马;进行恶意操作,例如任意篡改页面信息、删除文章等 进行大量的客户端攻击,如DDoS攻击;

获取客户端信息,例如用户的浏览历史、真实IP、开放端口等;

控制受害者机器向其他网站发起攻击;

结合其他漏洞,如CSRF漏洞,实施进一步作恶;

提升用户权限,包括进一步渗透网站;

传播跨站脚本,蠕虫等;

防御

防御的方式总的来说就是两方面。一方面是验证所有输入数据,有效检测攻击;另一方就是对所有输出数据进行适当的编码,以防止任何已成功注入的脚本在浏览器端运行。

1. 转义字符

一般会转(&、<、>、"、’、/)这6个字符。

比如说将

1

标签存储为

<script&gt</script&gt

2.CSP(内容安全策略)

CSP通过指定有效域——即浏览器认可的可执行脚本的有效来源——使服务器管理者有能力减少或消除XSS攻击所依赖的载体。一个CSP兼容的浏览器将会仅执行从白名单 域获取到的脚本文件,忽略所有的其他脚本

CSRF(Cross Site Request Forgery)跨站请求伪造

CSRF(Cross Site Request Forgery),即跨站请求伪造,是一种常见的Web攻击。

CSRF攻击过程的受害者用户登录网站A,输入个人信息,在本地保存服务器生成的cookie。

然后在A网站点击由攻击者构建一条恶意链接跳转到B网站,然后B网站携带着的用户cookie信息去访问B网站。

让A网站造成是用户自己访问的假相,从而来进行一些列的操作,常见的就是转账。

危害

通过基于受信任的输入form和对特定行为无需授权的已认证的用户来执行某些行为的web应用。已经通过被保存在用户浏览器中的cookie进行认证的用户将在完全无知的情况下发送HTTP请求到那个信任他的站点,进而进行用户不愿做的行为。

防御

大致要遵循以下几点规则:

  • Get 请求不对数据进行修改

  • 不让第三方网站访问到用户 Cookie

    • Cookie 的SameSite属性用来限制第三方 Cookie,从而减少安全风险。
  • 阻止第三方网站请求接口

  • 请求时附带验证信息,比如验证码或者Token

  • 验证 Referer, 验证一下发起请求的页面是不是我们的系统

  • 跨域资源共享(CORS)设置我们自己的页面

SQL脚本注入(SQL Injection)

SQL注入(SQL Injection),应用程序在向后台数据库传递SQL(Structured Query Language,结构化查询语言)时,攻击者将SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令

危害

1.获取不属于当前用户的管理权限

2.对数据库进行增删改查

防御

1、增加黑名单或者白名单验证

白名单验证一般指,检查用户输入是否是符合预期的类型、长度、数值范围或者其他格式标准

黑名单验证是指,若在用户输入中,包含明显的恶意内容则拒绝该条用户请求。在使用白名单验证时,一般会配合黑名单验证。

2、安全检测

在项目完成的时候,始终坚持安全检测。

3、防止系统敏感信息泄露

对数据表的访问权限进行严格控制,尽量限制用户不必要的访问权限

上传漏洞

指攻击者上传了一个可执行的文件到服务器并能够成功执行。

危害

上传漏洞与SQL注入或 XSS相比 , 其风险更大 , 如果 Web应用程序存在上传漏洞 ,攻击者上传的文件是Web脚本语言,服务器的Web容器解释并执行了用户上传的脚本,导致代码执行。如果上传的文件是Flash的策略文件crossdomain.xml,黑客用以控制Flash在该域下的行为。如果上传的文件是病毒、木马文件,黑客用以诱骗用户或者管理员下载执行。如果上传的文件是钓鱼图片或为包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼和欺诈。甚至攻击者可以直接上传一个webshell到服务器上

完全控制系统或致使系统瘫痪。

防御

客户端

  • javascript校验(一般只校验后缀名)

服务端校验

  • 文件头content-type字段校验(image/gif)

  • 文件内容头校验(GIF89a)

  • 后缀名黑名单校验

  • 后缀名白名单校验

  • 自定义正则校验

img标签的再次利用 onerror事件

通过将图片地址认为的设置错误,从而引发执行onerror事件. 系统执行攻击者的 代码,造成数据泄露

防御

可以参考CSP(内容安全策略)

点击劫持

这是一种欺骗性比较强,同时也需要用户高度参与才能完成的一种攻击。

通常的攻击步骤是这样的:

1、攻击者构造一个诱导用户点击的内容,如Web页面小游戏

2、将被攻击的页面放入到iframe当中

3、利用z-index等CSS样式将这个iframe叠加到小游戏的垂直方向的正上方

4、把iframe设置为100%透明度

5、受害者访问这个页面,肉眼看到的是一个小游戏,如果受到诱导进行了点击的话,实际上点击到的却是iframe中的页面

危害

点击劫持的危害在于,攻击利用了受害者的用户身份,在其不知情的情况下进行一些操作。

防御

X-FRAME-OPTIONS

设置页面是否可以在标签中显示

1、DENY:不能被嵌入到任何iframe或者frame中。

2、SAMEORIGIN:页面只能被本站页面嵌入到iframe或者frame中

3、ALLOW-FROM uri:只能被嵌入到指定域名的框架中

不安全的第三方依赖 CDN

原理

在我们的系统中引用的一些在线的第三方库,可能会存在被别人贡献的危害,是的我们的系统中执行一些非常规的操作

登录的账号密码不能明文传输

https安全加密

代码思考

项目结构划分

聊聊中后台前端应用:目录结构划分模式

0. 野生
js
project/src
   ├── api
   │   └── ...
   ├── assets
   │   └── ...
   ├── components
   │   └── ...
   ├── pages
   │   └── ...
   ├── plugins
   │   └── ...
   ├── router
   │   └── ...
   ├── types
   │   └── ...
   ├── App.vue
   └── main.ts
1. 分层

image-20230601093207030

DDD领域驱动设计结论--》领域或业务去拆分模块,再在每个模块中维护领域模型和业务规则等的相关文件

  • domain:这部分代码不会受页面的变化而改变,只有业务的变化或者对抽象的完善才会改变

    • txt
      domain
         ├── knowledge-base
         │   ├── model.ts
         │   ├── repository.ts
         │   ├── ...
         │   └── index.ts
         ├── knowledge-graph
         │   ├── model.ts
         │   ├── repository.ts
         │   ├── ...
         │   └── index.ts
         ├── robot
         │   ├── model.ts
         │   ├── repository.ts
         │   ├── ...
         │   └── index.ts
         └── ...
    • model.ts是对领域模型或业务实体的描述

    • repository.ts则主要用来存取资源。getter, setter

  • shared:共享资源是类型定义、工具函数、全局样式、基础组件等领域及业务无关的代码

    • txt
      shared
         ├── components
         │   ├── button
         │   │   └── ...
         │   ├── icon
         │   │   └── ...
         │   ├── ...
         │   └── index.ts
         ├── styles
         │   ├── normalize.scss
         │   ├── reset.scss
         │   └── utils.scss
         ├── types
         │   ├── ...
         │   └── index.ts
         ├── utils
         │   ├── date.ts
         │   ├── url.ts
         │   ├── ...
         │   └── index.ts
         └── ...
  • presentation:维护与领域及业务相关且受视图库/框架影响的代码

    • txt
      presentation
         ├── aspects
         │   ├── http.ts
         │   ├── router.ts
         │   ├── ...
         │   └── index.ts
         ├── layouts
         │   └── ...
         ├── router
         │   └── ...
         ├── views
         │   ├── knowledge-base
         │   │   ├── knowledge-base-detail
         │   │   │   ├── KnowledgeBaseDetail.vue
         │   │   │   ├── ...
         │   │   │   └── style.scss
         │   │   ├── knowledge-base-form
         │   │   │   ├── KnowledgeBaseForm.vue
         │   │   │   ├── ...
         │   │   │   └── style.scss
         │   │   ├── knowledge-base-list
         │   │   │   ├── KnowledgeBaseList.vue
         │   │   │   ├── ...
         │   │   │   └── style.scss
         │   │   ├── helper.ts
         │   │   └── KnowledgeBaseView.ts
         │   └── ...
         └── widgets
             └── ...
    • views 下是按领域或业务拆分模块(与领域层相对应)的视图/页面

    • widgets 是跨模块使用的部件/业务组件;

    • layouts 是视图/页面会用到的整体布局

    • router 是按菜单结构划分的路由配置

    • aspects 则是请求拦截、路由守卫等切面

「分层」模式的模块关系

2. 模块化

「分层」模式也足以应对复杂的前端项目,但它内聚性没有理想中那么高

txt
project/src
   ├── [domain-specific-module]
   │   ├── views
   │   │   ├── [detail-view]
   │   │   │   ├── [DetailViewComponent].vue
   │   │   │   ├── ...
   │   │   │   └── style.scss
   │   │   ├── [form-view]
   │   │   │   ├── [FormViewComponent].vue
   │   │   │   ├── ...
   │   │   │   └── style.scss
   │   │   └── [list-view]
   │   │       ├── [ListViewComponent].vue
   │   │       ├── ...
   │   │       └── style.scss
   │   ├── widgets
   │   │   └── [domain-specific-widget]
   │   │       └── ...
   │   ├── helper.ts
   │   ├── index.ts
   │   ├── model.ts
   │   ├── repository.ts
   │   └── ...
   ├── entry
   │   ├── aspects
   │   │   ├── http.ts
   │   │   ├── router.ts
   │   │   ├── ...
   │   │   └── index.ts
   │   ├── layouts
   │   │   └── ...
   │   └── router
   │       └── ...
   ├── shared
   │   └── ...
   ├── App.vue
   └── main.ts

差异点如下

  • presentation 下的 viewswidgets 拿掉后重命名为 entry,顾名思义,就是「入口」,汇集了其他各个模块的资源
  • domainviewswidgets 进行了整合,形成完全的按领域或业务拆分的模块
  • 整合后的 widgets 意义发生了变化,不再是跨模块的,而是当前模块特定的。虽说如此,但仍可被其他模块所使用——通过模块依赖指定的形式。每个领域/业务模块下有一个 index.ts 文件,用于描述该模块依赖哪些模块的什么资源(请求服务、部件/业务组件等),以及它向其他模块提供什么资源,有点像Angular
  • 为了提高灵活性,最好设计并实现一套模块注册与查找机制,以替代常规的 importexport。理想状况下,每个模块都可以跨应用使用。
  • 对于开发者来说,该如何看待这一个个模块呢?就当它们是 npm 包或 Git Submodule 好了。

「模块化」模式的模块关系

大型前端项目结构设计

shell
├── service                         # 后端接口管理
   ├── index.js                    # 接口管理出入口
   └── ...                         # 具体的不同业务/服务接口文件【S-1】
├── assets                          # 项目依赖资源管理
   └── imgs                        # 图片资源
   ├── style                       # 样式资源
   └── js                          # 依赖的第三方sdk之类的js资源
├── components                      # 项目组件目录
   ├── public                      # 公共组件/基础组件(比如基础的按钮/输入框等)
   │   ├── index.js                # 基础组件的注册文件【可选】
   │   ├── README.md               # 组件使用说明文档【可选】
   │   └── ...                     # 组件
   └── ....                        # 基础性的业务组件(有详细说明)【C-1】
├── pages                           
   ├── modules                     # 具体业务所归属的文件夹(可以用业务名称作为文件夹名字)
   │   ├── components              # 业务所用到的组件
   │   ├── views                   # 业务的所有页面
   │   ├── utils                   # 业务的工具集
   │   ├──	static                  # 业务所用到的静态资源
   │   ├── service                 # 业务的后端接口管理
   │   ├── store                   # 业务所用到的状态库(本结构基于Vue,这里是业务的Vuex)
   │   └── index.js                # 业务的唯一出口(包含路由与状态库)
   └── ....                        # 其他业务【P-1】
├── config                          # 项目的基础配置
   ├── index.js                    # 配置文件的出入口
   └── ...                         # 具体的配置文件【C-2】
├── router                          # 项目的路由管理
   ├── index.js                    # 路由出口
   └── ...                         # 与路由有关的其他文件【R-1】
├── store                           # 项目状态库的管理
   ├── index.js                    # 项目状态库的出入口
   └── ...                         # 具体的基础模块【S-2】
├── utils                           # 项目所用的工具集(封装的请求,表单的验证函数,时间格式化.....的工具)
   ├── index.js                    # 工具的入口
   └── ...                         # 具体的各个工具(请求封装、正则、验证......)【U-1】
├── main.js                          
├── App.vue

项目经验

我在税友这两年(上)

我在税友这两年(下)

登录认证

JWT

阮一峰教程

所有数据都保存在客户端,每次请求都发回服务器。JWT 就是这种方案的一个代表。

JWT 的三个部分依次如下。

  • Header(头部)

    • Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子。

    • javascript
      {
        "alg": "HS256",// 表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256)
        "typ": "JWT"// typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT
      }
    • 最后,将上面的 JSON 对象使用 Base64URL 算法(详见后文)转成字符串。

  • Payload(负载):部分也是一个 JSON 对象,用来存放实际需要传递的数据

    • iss (issuer):签发人

    • exp (expiration time):过期时间

    • sub (subject):主题

    • aud (audience):受众

    • nbf (Not Before):生效时间

    • iat (Issued At):签发时间

    • jti (JWT ID):编号

    • 除了官方字段,你还可以在这个部分定义私有字段

    • 这个 JSON 对象也要使用 Base64URL 算法转成字符串。

  • Signature(签名):Signature 部分是对前两部分的签名,防止数据篡改。

    • 首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名

    • js
      HMACSHA256(
        base64UrlEncode(header) + "." +
        base64UrlEncode(payload), // 解密的payload
        secret //密钥
      )

面经

彻底击碎行为问题

系统设计面试题精选

Released under the MIT License.