您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

前端鉴权的兄弟们:cookie、session、token、jwt、单点登录

时间:2021-07-29 10:22:34  来源:  作者:web前端攻城狮陈某

从状态说起

原文:「链接」

我们知道,HTTP 是无状态的。也就是说,HTTP 请求方和响应方之间无法维护状态,都是一次性的,它不知道前后的请求都发生了什么。

但有的场景下,我们需要维护状态。最典型的,一个用户登陆微博,发布、关注、评论,都应该是在登录后的用户状态下的。

「前端存储」

这就涉及到一发、一存、一带,发好办,登陆接口直接返回给前端,存储就需要前端想办法了。

前端的存储方式有很多。

  • 最矬的,挂到全局变量上,但这是个「体验卡」,一次刷新页面就没了
  • 高端点的,存到 cookie、localStorage 等里,这属于「会员卡」,无论怎么刷新,只要浏览器没清掉或者过期,就一直拿着这个状态。

前端存储这里不展开了。

有地方存了,请求的时候就可以拼到参数里带给接口了。


基石:cookie

cookie 也是前端存储的一种,但相比于 localStorage 等其他方式,借助 HTTP 头、浏览器能力,cookie 可以做到前端无感知。

一般过程是这样的:

  • 在提供标记的接口,通过 HTTP 返回头的 Set-Cookie 字段,直接「种」到浏览器上
  • 浏览器发起请求时,会自动把 cookie 通过 HTTP 请求头的 Cookie 字段,带给接口

「配置:Domain / Path」

Domain属性指定浏览器发出 HTTP 请求时,哪些域名要附带这个 Cookie。如果没有指定该属性,浏览器会默认将其设为当前 URL 的一级域名,比如 www.example.com 会设为 example.com,而且以后如果访问example.com的任何子域名,HTTP 请求也会带上这个 Cookie。如果服务器在Set-Cookie字段指定的域名,不属于当前域名,浏览器会拒绝这个 Cookie。

Path属性指定浏览器发出 HTTP 请求时,哪些路径要附带这个 Cookie。只要浏览器发现,Path属性是 HTTP 请求路径的开头一部分,就会在头信息里面带上这个 Cookie。比如,PATH属性是/,那么请求/docs路径也会包含该 Cookie。当然,前提是域名必须一致。

—— Cookie — JAVAScript 标准参考教程(alpha)

「配置:Expires / Max-Age」

Expires属性指定一个具体的到期时间,到了指定时间以后,浏览器就不再保留这个 Cookie。它的值是 UTC 格式。如果不设置该属性,或者设为null,Cookie 只在当前会话(session)有效,浏览器窗口一旦关闭,当前 Session 结束,该 Cookie 就会被删除。另外,浏览器根据本地时间,决定 Cookie 是否过期,由于本地时间是不精确的,所以没有办法保证 Cookie 一定会在服务器指定的时间过期。

Max-Age属性指定从现在开始 Cookie 存在的秒数,比如60 * 60 * 24 * 365(即一年)。过了这个时间以后,浏览器就不再保留这个 Cookie。

如果同时指定了Expires和Max-Age,那么Max-Age的值将优先生效。

如果Set-Cookie字段没有指定Expires或Max-Age属性,那么这个 Cookie 就是 Session Cookie,即它只在本次对话存在,一旦用户关闭浏览器,浏览器就不会再保留这个 Cookie。

—— Cookie — JavaScript 标准参考教程(alpha)

「配置:Secure / HttpOnly」

Secure属性指定浏览器只有在加密协议 HTTPS 下,才能将这个 Cookie 发送到服务器。另一方面,如果当前协议是 HTTP,浏览器会自动忽略服务器发来的Secure属性。该属性只是一个开关,不需要指定值。如果通信是 HTTPS 协议,该开关自动打开。

HttpOnly属性指定该 Cookie 无法通过 JavaScript 脚本拿到,主要是Document.cookie属性、XMLHttpRequest对象和 Request API 都拿不到该属性。这样就防止了该 Cookie 被脚本读到,只有浏览器发出 HTTP 请求时,才会带上该 Cookie。

—— Cookie — JavaScript 标准参考教程(alpha)

「HTTP 头对 cookie 的读写」

回过头来,HTTP 是如何写入和传递 cookie 及其配置的呢?

HTTP 返回的一个 Set-Cookie 头用于向浏览器写入「一条(且只能是一条)」cookie,格式为 cookie 键值 + 配置键值。例如:

Set-Cookie: username=jimu; domain=jimu.com; path=/blog; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly 

那我想一次多 set 几个 cookie 怎么办?多给几个 Set-Cookie 头(一次 HTTP 请求中允许重复)

Set-Cookie: username=jimu; domain=jimu.com
Set-Cookie: height=180; domain=me.jimu.com
Set-Cookie: weight=80; domain=me.jimu.com 

HTTP 请求的 Cookie 头用于浏览器把符合当前「空间、时间、使用方式」配置的所有 cookie 一并发给服务端。因为由浏览器做了筛选判断,就不需要归还配置内容了,只要发送键值就可以。

Cookie: username=jimu; height=180; weight=80 

「前端对 cookie 的读写」

前端可以自己创建 cookie,如果服务端创建的 cookie 没加HttpOnly,那恭喜你也可以修改他给的 cookie。

调用document.cookie可以创建、修改 cookie,和 HTTP 一样,一次document.cookie能且只能操作一个 cookie。

document.cookie = 'username=jimu; domain=jimu.com; path=/blog; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly'; 

调用document.cookie也可以读到 cookie,也和 HTTP 一样,能读到所有的非HttpOnlycookie。

console.log(document.cookie);
// username=jimu; height=180; weight=80 

(就一个 cookie 属性,为什么读写行为不一样?get / set 了解下)

「cookie 是维持 HTTP 请求状态的基石」

了解了 cookie 后,我们知道 cookie 是最便捷的维持 HTTP 请求状态的方式,大多数前端鉴权问题都是靠 cookie 解决的。当然也可以选用别的存储方式(后面也会多多少少提到)。

那有了存储工具,接下来怎么做呢?

应用方案:服务端 session

现在回想下,你刷卡的时候发生了什么?

其实你的卡上只存了一个 id(可能是你的学号),刷的时候物业系统去查你的信息、账户,再决定「这个门你能不能进」「这个鸡腿去哪个账户扣钱」。

这种操作,在前后端鉴权系统中,叫 session。

典型的 session 登陆/验证流程:

前端鉴权的兄弟们:cookie、session、token、jwt、单点登录

 

  • 浏览器登录发送账号密码,服务端查用户库,校验用户
  • 服务端把用户登录状态存为 Session,生成一个 sessionId
  • 通过登录接口返回,把 sessionId set 到 cookie 上
  • 此后浏览器再请求业务接口,sessionId 随 cookie 带上
  • 服务端查 sessionId 校验 session
  • 成功后正常做业务处理,返回结果

「Session 的存储方式」

显然,服务端只是给 cookie 一个 sessionId,而 session 的具体内容(可能包含用户信息、session 状态等),要自己存一下。存储的方式有几种:

  • redis(推荐):内存型数据库,redis中文官方网站。以 key-value 的形式存,正合 sessionId-sessionData 的场景;且访问快。
  • 内存:直接放到变量里。一旦服务重启就没了
  • 数据库:普通数据库。性能不高。

「Session 的过期和销毁」

很简单,只要把存储的 session 数据销毁就可以。

「Session 的分布式问题」

通常服务端是集群,而用户请求过来会走一次负载均衡,不一定打到哪台机器上。那一旦用户后续接口请求到的机器和他登录请求的机器不一致,或者登录请求的机器宕机了,session 不就失效了吗?

这个问题现在有几种解决方式。

  • 一是从「存储」角度,把 session 集中存储。如果我们用独立的 Redis 或普通数据库,就可以把 session 都存到一个库里。
  • 二是从「分布」角度,让相同 IP 的请求在负载均衡时都打到同一台机器上。以 Nginx 为例,可以配置 ip_hash 来实现。

但通常还是采用第一种方式,因为第二种相当于阉割了负载均衡,且仍没有解决「用户请求的机器宕机」的问题。

「node.js 下的 session 处理」

前面的图很清楚了,服务端要实现对 cookie 和 session 的存取,实现起来要做的事还是很多的。在npm中,已经有封装好的中间件,比如 express-session - npm,用法就不贴了。

这是它种的 cookie:

前端鉴权的兄弟们:cookie、session、token、jwt、单点登录

 

express-session - npm 主要实现了:

  • 封装了对cookie的读写操作,并提供配置项配置字段、加密方式、过期时间等。
  • 封装了对session的存取操作,并提供配置项配置session存储方式(内存/redis)、存储规则等。
  • 给req提供了session属性,控制属性的set/get并响应到cookie和session存取上,并给req.session提供了一些方法。

应用方案:token

session 的维护给服务端造成很大困扰,我们必须找地方存放它,又要考虑分布式的问题,甚至要单独为了它启用一套 Redis 集群。有没有更好的办法?

我又想到学校,在没有校园卡技术以前,我们都靠「学生证」。门卫小哥直接对照我和学生证上的脸,确认学生证有效期、年级等信息,就可以放行了。

回过头来想想,一个登录场景,也不必往 session 存太多东西,那为什么不直接打包到 cookie 中呢?这样服务端不用存了,每次只要核验 cookie 带的「证件」有效性就可以了,也可以携带一些轻量的信息。

这种方式通常被叫做 token。

前端鉴权的兄弟们:cookie、session、token、jwt、单点登录

 

token 的流程是这样的:

  • 用户登录,服务端校验账号密码,获得用户信息
  • 把用户信息、token 配置编码成 token,通过 cookie set 到浏览器
  • 此后用户请求业务接口,通过 cookie 携带 token
  • 接口校验 token 有效性,进行正常业务接口处理

「客户端 token 的存储方式」

在前面 cookie 说过,cookie 并不是客户端存储凭证的唯一方式。token 因为它的「无状态性」,有效期、使用限制都包在 token 内容里,对 cookie 的管理能力依赖较小,客户端存起来就显得更自由。但 web 应用的主流方式仍是放在 cookie 里,毕竟少操心。

「token 的过期」

那我们如何控制 token 的有效期呢?很简单,把「过期时间」和数据一起塞进去,验证时判断就好。

token 的编码

编码的方式丰俭由人。

「base64」

比如 node 端的 cookie-session - npm 库

不要纠结名字,其实是个 token 库,但保持了和 express-session - npm 高度一致的用法,把要存的数据挂在 session 上

默认配置下,当我给他一个 userid,他会译成这样:

前端鉴权的兄弟们:cookie、session、token、jwt、单点登录

 

这里的 eyJ1c2VyaWQiOiJhIn0=,就是 {"userid":"abb”} 的 base64 而已。

「防篡改」

那问题来了,如果用户 cdd 拿{"userid":"abb”}转了个 base64,再手动修改了自己的 token 为 eyJ1c2VyaWQiOiJhIn0=,是不是就能直接访问到 abb 的数据了?

是的。所以看情况,如果 token 涉及到敏感权限,就要想办法避免 token 被篡改。

解决方案就是给 token 加签名,来识别 token 是否被篡改过。例如在 cookie-session - npm 库中,增加两项配置:

secret: 'iAmSecret',
signed: true, 

这样会多种一个 .sig cookie,里面的值就是 {"userid":"abb”} 和 iAmSecret通过加密算法计算出来的,常见的比如HmacSHA256 类 (System.Security.Cryptography) | Microsoft Docs。

前端鉴权的兄弟们:cookie、session、token、jwt、单点登录

 

好了,现在 cdd 虽然能伪造出eyJ1c2VyaWQiOiJhIn0=,但伪造不出 sig 的内容,因为他不知道 secret。

「JWT」

但上面的做法额外增加了 cookie 数量,数据本身也没有规范的格式,所以 JSON Web Token Introduction - jwt.io 横空出世了。

JSON Web Token (JWT) 是一个开放标准,定义了一种传递 JSON 信息的方式。这些信息通过数字签名确保可信。

它是一种成熟的 token 字符串生成方案,包含了我们前面提到的数据、签名。不如直接看一下一个 JWT token 长什么样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiJhIiwiaWF0IjoxNTUxOTUxOTk4fQ.2jf3kl_uKWRkwjOP6uQRJFqMlwSABcgqqcJofFH5XCo 

这串东西是怎么生成的呢?看图:

前端鉴权的兄弟们:cookie、session、token、jwt、单点登录

 

类型、加密算法的选项,以及 JWT 标准数据字段,可以参考 RFC 7519 - JSON Web Token (JWT)

node 上同样有相关的库实现:express-jwt - npm koa-jwt - npm

refresh token

token,作为权限守护者,最重要的就是「安全」。

业务接口用来鉴权的 token,我们称之为 access token。越是权限敏感的业务,我们越希望 access token 有效期足够短,以避免被盗用。但过短的有效期会造成 access token 经常过期,过期后怎么办呢?

一种办法是,让用户重新登录获取新 token,显然不够友好,要知道有的 access token 过期时间可能只有几分钟。

另外一种办法是,再来一个 token,一个专门生成 access token 的 token,我们称为 refresh token。

  • access token 用来访问业务接口,由于有效期足够短,盗用风险小,也可以使请求方式更宽松灵活
  • refresh token 用来获取 access token,有效期可以长一些,通过独立服务和严格的请求方式增加安全性;由于不常验证,也可以如前面的 session 一样处理

有了 refresh token 后,几种情况的请求流程变成这样:

前端鉴权的兄弟们:cookie、session、token、jwt、单点登录

 

如果 refresh token 也过期了,就只能重新登录了。

session 和 token

session 和 token 都是边界很模糊的概念,就像前面说的,refresh token 也可能以 session 的形式组织维护。

狭义上,我们通常认为 session 是「种在 cookie 上、数据存在服务端」的认证方案,token 是「客户端存哪都行、数据存在 token 里」的认证方案。对 session 和 token 的对比本质上是「客户端存 cookie / 存别地儿」、「服务端存数据 / 不存数据」的对比。

「客户端存 cookie / 存别地儿」

存 cookie 固然方便不操心,但问题也很明显:

  • 在浏览器端,可以用 cookie(实际上 token 就常用 cookie),但除了浏览器端,没有 cookie 怎么办?
  • cookie 是浏览器在域下自动携带的,这就容易引发 CSRF 攻击(前端安全系列(二):如何防止CSRF攻击?- 美团技术团队)

存别的地方,可以解决没有 cookie 的场景;通过参数等方式手动带,可以避免 CSRF 攻击。

「服务端存数据 / 不存数据」

  • 存数据:请求只需携带 id,可以大幅缩短认证字符串长度,减小请求体积
  • 不存数据:不需要服务端整套的解决方案和分布式处理,降低硬件成本;避免查库带来的验证延迟

单点登录

前面我们已经知道了,在同域下的客户端/服务端认证系统中,通过客户端携带凭证,维持一段时间内的登录状态。

但当我们业务线越来越多,就会有更多业务系统分散到不同域名下,就需要「一次登录,全线通用」的能力,叫做「单点登录」。

“虚假”的单点登录(主域名相同)

简单的,如果业务系统都在同一主域名下,比如wenku.baidu.com tieba.baidu.com,就好办了。可以直接把 cookie domain 设置为主域名 baidu.com,百度也就是这么干的。

前端鉴权的兄弟们:cookie、session、token、jwt、单点登录

 

“真实”的单点登录(主域名不同)

比如滴滴这么潮的公司,同时拥有didichuxing.com xiaojukeji.com didiglobal.com等域名,种 cookie 是完全绕不开的。

这要能实现「一次登录,全线通用」,才是真正的单点登录。

这种场景下,我们需要独立的认证服务,通常被称为 SSO。

「一次「从 A 系统引发登录,到 B 系统不用登录」的完整流程」

前端鉴权的兄弟们:cookie、session、token、jwt、单点登录

 

  • 用户进入 A 系统,没有登录凭证(ticket),A 系统给他跳到 SSO
  • SSO 没登录过,也就没有 sso 系统下没有凭证(注意这个和前面 A ticket 是两回事),输入账号密码登录
  • SSO 账号密码验证成功,通过接口返回做两件事:一是种下 sso 系统下凭证(记录用户在 SSO 登录状态);二是下发一个 ticket
  • 客户端拿到 ticket,保存起来,带着请求系统 A 接口
  • 系统 A 校验 ticket,成功后正常处理业务请求
  • 此时用户第一次进入系统 B,没有登录凭证(ticket),B 系统给他跳到 SSO
  • SSO 登录过,系统下有凭证,不用再次登录,只需要下发 ticket
  • 客户端拿到 ticket,保存起来,带着请求系统 B 接口

「完整版本:考虑浏览器的场景」

上面的过程看起来没问题,实际上很多 App 等端上这样就够了。但在浏览器下不见得好用。

看这里:

前端鉴权的兄弟们:cookie、session、token、jwt、单点登录

 

对浏览器来说,SSO 域下返回的数据要怎么存,才能在访问 A 的时候带上?浏览器对跨域有严格限制,cookie、localStorage 等方式都是有权限制的。

这就需要也只能由 A 提供 A 域下存储凭证的能力。一般我们是这么做的:

前端鉴权的兄弟们:cookie、session、token、jwt、单点登录

 

图中我们通过颜色把浏览器当前所处的域名标记出来。注意图中灰底文字说明部分的变化。

  • 在 SSO 域下,SSO 不是通过接口把 ticket 直接返回,而是通过一个带 code 的 URL 重定向到系统 A 的接口上,这个接口通常在 A 向 SSO 注册时约定
  • 浏览器被重定向到 A 域下,带着 code 访问了 A 的 callback 接口,callback 接口通过 code 换取 ticket
  • 这个 code 不同于 ticket,code 是一次性的,暴露在 URL 中,只为了传一下换 ticket,换完就失效
  • callback 接口拿到 ticket 后,在自己的域下 set cookie 成功
  • 在后续请求中,只需要把 cookie 中的 ticket 解析出来,去 SSO 验证就好
  • 访问 B 系统也是一样

总结

  • HTTP 是无状态的,为了维持前后请求,需要前端存储标记
  • cookie 是一种完善的标记方式,通过 HTTP 头或 js 操作,有对应的安全策略,是大多数状态管理方案的基石
  • session 是一种状态管理方案,前端通过 cookie 存储 id,后端存储数据,但后端要处理分布式问题
  • token 是另一种状态管理方案,相比于 session 不需要后端存储,数据全部存在前端,解放后端,释放灵活性
  • token 编码技术,通常基于 base64,或增加加密算法防篡改,jwt 是一种成熟的编码方案
  • 在复杂系统中,token 可通过 service token、refresh token 得分权,同时满足安全性和用户体验
  • session 和 token 的对比就是「用不用cookie」和「后端存不存」的对比
  • 单点登录要求不同域下的系统「一次登录,全线通用」,通常由独立的 SSO 系统记录登录状态、下发 ticket,各业务系统配合存储和认证 ticket


Tags:单点登录   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  Tags: 单点登录  点击:(8)  评论:(0)  加入收藏
1. 概述1.1. 什么是SSO?单点登录( Single Sign-On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统中,用户只需要 登录一次 就可以访问...【详细内容】
2021-08-10  Tags: 单点登录  点击:(80)  评论:(0)  加入收藏
从状态说起原文:「链接」我们知道,HTTP 是无状态的。也就是说,HTTP 请求方和响应方之间无法维护状态,都是一次性的,它不知道前后的请求都发生了什么。但有的场景下,我们需要维护状...【详细内容】
2021-07-29  Tags: 单点登录  点击:(94)  评论:(0)  加入收藏
通过前面几篇文章我们详细的介绍了SpringSecurity的使用,本文我们来看下,结合JWT来实现单点登录操作。一、什么是单点登陆  单点登录(Single Sign On),简称为 SSO,是目...【详细内容】
2020-12-14  Tags: 单点登录  点击:(16880)  评论:(0)  加入收藏
单点登录实现中,系统之间的协议对接是非常重要的一环,一般涉及的标准协议类型有 CAS、OAuth、OpenID Connect、SAML,本文将对四种主流 SSO协议进行概述性的介绍,并比较其异同,读...【详细内容】
2020-11-10  Tags: 单点登录  点击:(224)  评论:(0)  加入收藏
现在大部分的网络应用,登录、注册、密码加密保存、token 管理等功能都是必要的。为了让用户的隐私更能得到保障,使用起来更方便,OAuth 协议和单点登录系统也就应运而生。今天...【详细内容】
2020-08-17  Tags: 单点登录  点击:(80)  评论:(0)  加入收藏
看过不少JWT和单点登录系统的文章,自己也算略知一二。这里就根据自己的实际开发经验谈一下我的理解。大致可以总结为以下三种方案:1. 纯Jwt2. Jwt + 认证中心Redis3. Jwt + 认...【详细内容】
2020-07-19  Tags: 单点登录  点击:(352)  评论:(0)  加入收藏
多处使用,而在架构单点登录时,也会遇到一些小问题,在不同的应用环境中可以采用不同的单点登录实现方案来满足需求。我将以我所遇到的应用环境以及在其中所经历的各个阶段与大家...【详细内容】
2019-09-27  Tags: 单点登录  点击:(100)  评论:(0)  加入收藏
需求多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。A 网站和 B 网站是同一家公司的关联服务。现在要求,用户只要在其中一个网站登录,再访问另一个网站...【详细内容】
2019-09-24  Tags: 单点登录  点击:(373)  评论:(0)  加入收藏
▌简易百科推荐
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(1)  评论:(0)  加入收藏
程序是如何被执行的  程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(9)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(19)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(23)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(24)  评论:(0)  加入收藏
一个项目的大部分API,测试用例在参数和参数值等信息会有很多相似的地方。我们可以复制API,复制用例来快速生成,然后做细微调整既可以满足我们的测试需求1.复制API:在菜单发布单...【详细内容】
2021-12-14  AutoMeter    Tags:AutoMeter   点击:(20)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条