成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

個(gè)人信息保護(hù)法,重要細(xì)節(jié)有哪些?

安全 應(yīng)用安全
本篇文章是我對在 2021年08月01日深圳 GOTC 大會(huì)的《探索類型友好的 Node.js Web 框架》分享內(nèi)容的整理與總結(jié)。

 [[418829]]

隨著 TypeScript 的流行,類型系統(tǒng)也逐步進(jìn)入了大家的視野,類型安全相關(guān)的問題也受到了更多人的關(guān)注,那今天我就以這個(gè)角度帶大家感受  Farrow 在類型安全方面優(yōu)秀方案的設(shè)計(jì)與思考,希望對大家能有所啟發(fā)。

在本篇文章中,我將為大家?guī)硪韵碌膬?nèi)容:

  • 類型安全 What & Why?

  • 當(dāng)前 Node.js 主流 Web 框架現(xiàn)狀

  • 當(dāng)下的 API 設(shè)計(jì)中的類型問題

  • Farrow 類型安全方案

  • Farrow 未來規(guī)劃

好,那我們現(xiàn)在開始。

類型安全

關(guān)于類型安全,可能很多同學(xué)已經(jīng)有所了解,也了解過 Soundness [1] 這個(gè)詞,但也該也有許多同學(xué)不甚了解。

不了解的同學(xué),你可以暫且將它簡單的理解為:

變量的行為與它的類型相匹配,不存在運(yùn)行時(shí)的類型錯(cuò)誤。

在 JavaScript 中進(jìn)行下面幾個(gè)操作:

  • 訪問 null 的屬性

  • 將 string 類型當(dāng)作 number 類型做運(yùn)算

  • 調(diào)用對象不存在的方法

都會(huì)在運(yùn)行時(shí)拋出類型錯(cuò)誤。

那我們?yōu)槭裁匆非箢愋桶踩?/p>

Well typed programs cannot go wrong.—— By Robin Milner 1978 《A Theory of Type Polymorphism in Programming》 [2]

正如上面這句話說的,類型系統(tǒng)可以有效的提升程序的正確性:

  • 盡可能在編譯期通過類型檢查提前捕獲可能的程序錯(cuò)誤,提高代碼的健壯性

  • 配合編輯器類型提示,類型檢查是比單元測試反饋更快、更早、覆蓋更全面的實(shí)時(shí)測試

  • 符合類型安全準(zhǔn)則的代碼,往往是設(shè)計(jì)更合理、質(zhì)量更高、編寫更優(yōu)雅的、表達(dá)更清晰的

類型檢查的優(yōu)勢不用多說,要讓我們的代碼達(dá)到類型安全的狀態(tài),往往需要我們對要解決的問題進(jìn)行很好的建模,所以從這個(gè)角度看,類型系統(tǒng)也可以幫助我們寫出設(shè)計(jì)更合理、質(zhì)量更高的代碼。

主流框架現(xiàn)狀

之前我們在實(shí)際的項(xiàng)目開發(fā)中遇到過 Node.js 框架選型的問題,經(jīng)過調(diào)研,我們發(fā)現(xiàn)主流的 Node.js 框架: Express.js 、 Koa 、 EggJS 、 Hapi 、 Restify 、 Fastify 等都是用  JavaScript 實(shí)現(xiàn)的,他們充分發(fā)揮了  Javascript 的能力,但 從類型安全的視角看,當(dāng)前 Web 框架的設(shè)計(jì)存在諸多問題。

API 設(shè)計(jì)類型問題

接下來,我們就以 Express 為例來看一下。

請求意外掛起(Hanging Request)

我們發(fā)現(xiàn)以 Express 這樣的中間件設(shè)計(jì),它允許請求可以不被響應(yīng),也無法通過 TypeScript 的類型檢查得到約束和提示。

  1. app.use((req, res, next) => { 
  2.   // do nothing 
  3. }); 

錯(cuò)誤的相應(yīng)內(nèi)容(Wrong Response)

同樣的,我們無法保證 header -> body 這樣正確的的響應(yīng)次序

  1. app.use((req, res, next) => { 
  2.   // body 提前發(fā)送 
  3.   res.end('xxx'); 
  4.   // header 必須在 body 之前發(fā)送,這里報(bào)錯(cuò)或 warning 
  5.   res.header('Content-Type''text/html'); 
  6. }); 

也無法在編譯期約束只發(fā)送一次 body

  1. app.use((req, res, next) => { 
  2.   // body 提前發(fā)送 
  3.   res.end('xxx'); 
  4.   // body 只能發(fā)送一次,這里報(bào)錯(cuò)或 warning 
  5.   res.json({ error: true }); 
  6. }); 

而這些都會(huì)導(dǎo)致錯(cuò)誤的響應(yīng)內(nèi)容。

篡改對象屬性(Monkey Patching)

在 JavaScript 中,我們可以任意的修改對象的屬性,但修改 req/res 或 ctx 污染全鏈路中間件的類型。這會(huì)導(dǎo)致,在任意一個(gè)中間件中,你都無法知道傳到當(dāng)前中間件的對象中到底有哪些屬性和方法。

  1. app.use((req, res, next) => { 
  2.   // what type of res.locals 
  3.   res.locals.a = 1
  4.   next(); 
  5. }); 
  6.  
  7. app.use((req, res, next) => { 
  8.   // what type of res.locals 
  9.   console.log(res.locals.a); 
  10. }); 

當(dāng)然有些框架支持一些類型標(biāo)注的方案,來解決類型提示上的問題,但這并沒有從根本上解決問題,從類型系統(tǒng)的角度來看,動(dòng)態(tài)追加的屬性或方法,與靜態(tài)標(biāo)注的類型有本質(zhì)矛盾,正確的方式是 讓靜態(tài)類型決定能否賦值屬性,而非屬性賦值決定是否包含特定類型。

無運(yùn)行時(shí)驗(yàn)證(No Runtime Validation)

在當(dāng)前 TypeScript 官方提供的工具鏈中,TypeScript 類型在編譯后都被抹去,的確在大多數(shù)場景下,編譯階段前類型系統(tǒng)就完成了它的任務(wù),但這也導(dǎo)致了一個(gè)嚴(yán)重的問題,請求的內(nèi)容是未知的,通常需要手動(dòng)進(jìn)行校驗(yàn)。

  1. app.use((req, res, next) => { 
  2.   req.body; // body type is any/unknown 
  3.   req.query; // query type is any/unknown 
  4.   const body = req.body as MyBodyType; // type wll be eliminated 
  5. }); 

如果請求參數(shù)比較復(fù)雜,通常需要編寫很復(fù)雜的校驗(yàn)邏輯。

不友好的類型推導(dǎo)(Poor Type Inference)

現(xiàn)有框架在請求內(nèi)容和響應(yīng)內(nèi)容的類型方面基本沒有提供比較好的類型推導(dǎo)方案,很多時(shí)候我們需要手動(dòng)的類型校驗(yàn) + 類型轉(zhuǎn)換。

  1. app.get('/user/:userId', (req, res, next) => { 
  2.   req.params.userId; // no type infer 
  3.   const params = req.params as { userId: string }; 
  4.   const userId = Number(params.userId); // 必須每次手動(dòng) transform 
  5. }); 

問題

到現(xiàn)在,我們已經(jīng)提到了 5 條現(xiàn)有 API 設(shè)計(jì)中的類型問題:

  1. Hanging Request(請求意外掛起)

  2. Wrong Response(錯(cuò)誤響應(yīng)內(nèi)容)

  3. Monkey Patching(篡改對象屬性)

  4. No Runtime Validation(無運(yùn)行時(shí)驗(yàn)證)

  5. Poor Type Inference(不友好的類型推導(dǎo))

雖然這些框架不是使用 TypeScript 實(shí)現(xiàn),但它們都提供了 @types/* 的類型包,但依舊存在諸多類型上的問題,可見只靠 *.d.ts,并不能獲得充分的類型友好和類型安全特性。

我們對這些問題和現(xiàn)有的 Node.js 框架進(jìn)行了系統(tǒng)性的調(diào)研和考量,發(fā)現(xiàn):

  • 基于 Express/Koa 可以用打補(bǔ)丁的方式解決一兩種類型問題,但不能從根本上解決問題

  • Fastify 提供了基于 JSON Schema 的運(yùn)行時(shí)校驗(yàn)請求內(nèi)容的方案,但方案與類型系統(tǒng)不貼合

  • 要充分解決系統(tǒng)性問題,則需要基于 TypeScript 做全盤的思考

  • Type-First Development 類型優(yōu)先開發(fā)

  • Type-Driven Development 類型驅(qū)動(dòng)開發(fā)

為了做到這些和解決上面提到的問題,我們就需要一個(gè)新的類型安全的服務(wù)端框架。

類型安全的服務(wù)端框架設(shè)計(jì)目標(biāo)

根據(jù)之前的問題,我們可以得到類型安全的服務(wù)端框架設(shè)計(jì)目標(biāo):

  • Prevent Hanging Request(阻止請求意外掛起)

  • Refuse Wrong Response(拒絕錯(cuò)誤響應(yīng)內(nèi)容)

  • No need to Monkey-Patching(無需篡改對象屬性)

  • Embedded Runtime-Validation(內(nèi)置運(yùn)行時(shí)驗(yàn)證)

  • Excellent Type Inference(出色的類型推導(dǎo))

Farrow 作者:做到之前做不到,做好之前能做到。

從而就有了 Farrow 這樣一個(gè)框架,接下來我就向大家介紹一下,F(xiàn)arrow 的一些設(shè)計(jì)和它是如何做到上面所說的事情。

Farrow-Http 設(shè)計(jì)

Prevent Hanging Request & Refuse Wrong Response

首先,為了可以做到 阻止請求意外掛起 和 拒絕錯(cuò)誤響應(yīng)內(nèi)容,F(xiàn)arrow 重新設(shè)計(jì)了中間件,取消了響應(yīng)參數(shù),通過返回值表達(dá)響應(yīng)結(jié)果。

  1. import { Http, Response } from 'farrow-http'
  2.  
  3. const http = Http(); 
  4.  
  5. http.use((request, next) => { 
  6.   // response is return type 
  7.   return Response.text(request.pathname); 
  8. }); 

這樣 TypeScript 也可以檢查函數(shù)返回值類型是否滿足約束,沒有響應(yīng)或者響應(yīng)錯(cuò)誤類型都會(huì)類型報(bào)錯(cuò)。

 

 

 

 

Prevent Wrong Response

為了進(jìn)一步解決錯(cuò)誤的相應(yīng)內(nèi)容的問題, Farrow 設(shè)計(jì)了 Virtual Response 虛擬響應(yīng)對象,Response.text 等方法構(gòu)造了樸素?cái)?shù)據(jù),類似 Virtual DOM,并未直接產(chǎn)生作用,多次使用將 merged 到一起,F(xiàn)arrow 框架內(nèi)部最終統(tǒng)一按照正確順序處理 header -> body 的次序和類型。

  1. import { Http, Response } from 'farrow-http'
  2.  
  3. const http = Http(); 
  4.  
  5. http.use((request, next) => { 
  6.   // response is return type 
  7.   return Response.text(request.pathname) 
  8.     .header('abc''efg'
  9.     .text('changed text'); 
  10. }); 

No need to Monkey-Patching(Request)

為了解決 Monkey-Patching 的問題,即不再推薦和引導(dǎo)開發(fā)者去修改 req 請求對象,F(xiàn)arrow 設(shè)計(jì)了 Virtual Request 虛擬請求對象,所以傳入中間件的請求對象不是原生  req 對象,而是從中提取的 plain data,所以可以通過 next(newRequest) 向后傳遞新的 request 對象,無需修改原對象。

  1. import { Http, Response } from 'farrow-http'
  2.  
  3. const http = Http(); 
  4.  
  5. http.use((request, next) => { 
  6.   return next({ 
  7.     ...request, 
  8.     pathname: '/another/pathname'
  9.   }); 
  10. }); 
  11.  
  12. http.use((request, next) => { 
  13.   request.pathname; // is equal to /another/pathname 
  14. }); 

No need to Monkey-Patching(Response)

為了進(jìn)一步解決 Monkey-Patching 的問題,F(xiàn)arrow 重新設(shè)計(jì)了中間件的管理機(jī)制,next 將會(huì)返回下游中間件的 response 對象,可以加以后續(xù)處理,這樣就可以做到無需修改 res/ctx.body ,immutable 比 mutable 更加類型友好, prefer immutable。

  1. import { Http, Response } from 'farrow-http'
  2.  
  3. const http = Http(); 
  4.  
  5. http.use((request, next) => { 
  6.   let response = await next(); 
  7.   // 合并,組合,過濾,拼裝新的 response 
  8.   return Response.header('abc''efg').merge(response); 
  9. }); 
  10.  
  11. http.use((request, next) => { 
  12.   return Response.text('hello world!'); 
  13. }); 

No need to Monkey-Patching(Middleware)

雖然之前的方面解決了修改請求對象的問題,但中間件間共享變量的需求依舊沒有被解決,所以 Farrow 提供了 Context + Hooks 的方案,他們的工作機(jī)制類似 React Context 和 React Hooks,類似跨組件傳遞數(shù)據(jù)那樣,跨中間件傳遞 Context Data,這樣中間件間的共享變量就無需掛載到 req 對象上了,并且得益于 Node.js 的新特性 Async hooks,F(xiàn)arrow 能夠提供按需的、分布式的、細(xì)粒度的、關(guān)注度分離的、類型安全的 Context Passing 機(jī)制。

  1. import { Http, Response, createContext } from 'farrow-http'
  2.  
  3. const http = Http(); 
  4.  
  5. // 創(chuàng)建 Context 
  6. const AuthContext = createContext<Auth | null>(null); 
  7.  
  8. // 更新 Context 
  9. http.use(async (request, next) => { 
  10.   AuthContext.set(await getAuth(request)); 
  11.   return next(); 
  12. }); 
  13.  
  14. // 不管中間插入多少中間件,request/response 類型都不會(huì)污染 
  15.  
  16. // 消費(fèi) Context 
  17. http.use((request, next) => { 
  18.   // 跨中間件訪問 context 數(shù)據(jù) 
  19.   let auth = AuthContext.get(); 
  20.   return Response.text('hello world!'); 
  21. }); 

Embedded Runtime-Validation & Excellent Type Inference(Schema)

為了提供運(yùn)行時(shí)驗(yàn)證和更友好的類型推導(dǎo)能力,F(xiàn)arrow 設(shè)計(jì)了一套對 TypeScript 開發(fā)者非常友好的 Schema Builder,從而基于 Schema 提供了 Runtime Validation 機(jī)制,允許開發(fā)者使用 Schema Builder 去描述請求的形狀,基于這個(gè)形狀 Farrow 會(huì)自動(dòng)推導(dǎo)出請求對象的類型,這樣就保證了在運(yùn)行時(shí)請求對象對象的值將會(huì)滿足 Schema 所描述的形狀。這樣我們就同時(shí)提供了運(yùn)行時(shí)校驗(yàn)和友好的類型推導(dǎo)。

  1. import { Http, Response } from 'farrow-http'
  2. import { Int } from 'farrow-schema'
  3.  
  4. const http = Http(); 
  5.  
  6. http 
  7.   .match({ 
  8.     pathname: '/user'
  9.     method: 'post'
  10.     body: { 
  11.       userId: Int, 
  12.       userName: String, 
  13.       userAge: Int, 
  14.     }, 
  15.   }) 
  16.   .use((request, next) => { 
  17.     // request.body is { userId, userName, userAge } 
  18.     console.log('userId', request.body.userId); 
  19.     console.log('userName', request.body.userName); 
  20.     console.log('userAge', request.body.userAge); 
  21.   }); 

Embedded Runtime-Validation & Excellent Type Inference(URL)

后來我們發(fā)現(xiàn)很多時(shí)候我們又好像并不需要這么復(fù)雜的數(shù)據(jù)結(jié)構(gòu),所以 Farrow 提供了一種更簡單的描述方式:

  1. import { Http, Response } from 'farrow-http'
  2. import { Int } from 'farrow-schema'
  3.  
  4. const http = Http(); 
  5.  
  6. http 
  7.   .get('/greet/<name:string>?<age:int>&farrow=type-safety'
  8.   .use((request, next) => { 
  9.     // type infer for request from url 
  10.     console.log('name', request.params.name); 
  11.     console.log('age', request.query.age); 
  12.     console.log('farrow', request.query.farrow); 
  13.   }); 

它是基于 TypeScript 4.1 發(fā)布的 Template literal type 特性實(shí)現(xiàn)的,從 URL 中提取 TypeScript 類型,然后自動(dòng)識別是 params 參數(shù)還是 query 參數(shù),自動(dòng)將 String 轉(zhuǎn)換成標(biāo)記的 Int 、Boolean 等 Schema 類型,基于這個(gè)我們也可以同時(shí)提供了運(yùn)行時(shí)校驗(yàn)和友好的類型推導(dǎo)。

以上 farrow-http 運(yùn)用 Type-First Development 思想和 React 啟發(fā)的函數(shù)式/immutable 理念,系統(tǒng)性地提升了 Web Framework 的類型安全水平,解決了以下的問題:

  • Prevent Hanging Request(阻止請求意外掛起)√

  • Refuse Wrong Response(拒絕錯(cuò)誤響應(yīng)內(nèi)容)√

  • No need to Monkey-Patching(無需篡改對象屬性)√

  • Embedded Runtime-Validation(內(nèi)置運(yùn)行時(shí)驗(yàn)證)√

  • Excellent Type Inference(出色的類型推導(dǎo))√

新的挑戰(zhàn):端到端類型同步

farrow-Http 優(yōu)化了 Service Side 的類型安全,只解決了一半問題,End-to-end typing 將是一個(gè)新的問題 Client Side 如何復(fù)用 Service Side 的類型?Client Side 類型如何跟 Service Side 保持一致和同步?所以我們重新思考: BFF 應(yīng)該為前端提供什么?

  • 傳統(tǒng) BFF:為前端提供 data

  • 現(xiàn)代 BFF:為前端提供 data 和 type

  • 后現(xiàn)代 BFF:為前端提供 data,type 和 code

為了做到這些,F(xiàn)arrow 提供了一個(gè)新的方案:farrow-api。

Farrow-API 設(shè)計(jì)

Farrow 采用了 Introspection + Codegen 的方式來實(shí)現(xiàn)為前端提供 data,type 和 code。提供了類似 GraphQL 的 Introspection 機(jī)制,支持拉取 farrow-api 的 Schema 數(shù)據(jù),然后通過 Code Generation 生成 TypeScript Type 和 HTTP Client Code。

 

 

 

 

在服務(wù)器端,描述請求和響應(yīng)的形狀,然后聚合成 Farrow API

 

 

 

 

然后為該 API 實(shí)現(xiàn)請求處理函數(shù)

 

 

 

 

然后啟動(dòng) Server,在客戶端就可以生成下面的代碼

 

 

 

 

而在客戶端開發(fā)者只需要引入生成的函數(shù),然后調(diào)用

 

 

 

 

除此之外,farrow-api 還支持其他描述 API 的屬性,比如 @deprecated 標(biāo)記

 

 

 

 

至此 Farrow 實(shí)現(xiàn)了服務(wù)器端的類型安全,也解決了 C/S 模型下的類型同步問題。

Farrow 藍(lán)圖和未來展望

優(yōu)勢

除了類型安全之外,F(xiàn)arrow 的設(shè)計(jì)還帶來了另外的一些優(yōu)勢,擁有 Schema 之后可以形成接口的知識庫,知識庫可以用來做很多事情,函數(shù)級別的接口監(jiān)控、測試和版本控制。

未來規(guī)劃

Farrow 目前的規(guī)劃中有兩個(gè)主要的方向:

首先是生態(tài),因?yàn)槟壳?Farrow 的開發(fā)團(tuán)隊(duì)比較小,所以不管是一些基礎(chǔ)的工具庫還是文檔、最佳實(shí)踐都是缺失和不完善的,但這些內(nèi)容缺失導(dǎo)致很少的開發(fā)者能夠了解 Farrow 并使用它,所以這將是接下來 Farrow 團(tuán)隊(duì)的比較主要的工作方向。除此之外,是基礎(chǔ)能力。Farrow 目前還不夠系統(tǒng),我們還沒有將它的潛力完全發(fā)揮出來,所以也會(huì)有一大部分精力投入在繼續(xù)探索它能力的邊界。

Bonus: farrow-express & farrow-koa

需要告訴大家的一個(gè)好消息是:Farrow 現(xiàn)在已經(jīng)可以通過 adapter 復(fù)用 Express/Koa 等生態(tài):

farrow-express:將 farrow-http 運(yùn)行在 Express App 上 farrow-koa:將 farrow-http 運(yùn)行在 Koa App 上

總結(jié)

在本篇文章中

  • 我們了解了類型安全的定義及其價(jià)值

  • 我們看到了當(dāng)前 Node.js Web 框架中存在的類型問題

  • 我們看到了 Farrow-HTTP 如何通過類型優(yōu)先和函數(shù)式的思路,系統(tǒng)性地改善類型問題

  • 我們看到了 Farrow-API 如何貫通前后端類型

  • 我們了解了現(xiàn)在立刻能就在 Express/Koa 等應(yīng)用中使用 Farrow 的方式

  • 我們了解了 Farrow 以及其它追求類型安全的框架將來要解決的問題

 

 

責(zé)任編輯:張燕妮 來源: 肖颯lawyer
相關(guān)推薦

2020-10-27 16:18:15

安全 信息安全數(shù)據(jù)信息

2020-10-30 09:38:02

個(gè)人信息保護(hù)法網(wǎng)絡(luò)安全信息安全

2021-08-20 16:19:14

信息安全網(wǎng)絡(luò)安全個(gè)人信息保護(hù)法

2020-10-06 18:40:44

個(gè)人信息保護(hù)法網(wǎng)絡(luò)安全信息安全

2021-08-24 10:04:55

數(shù)據(jù)安全信息隱私

2020-10-24 17:30:01

個(gè)人信息保護(hù)法網(wǎng)絡(luò)空間信息安全

2020-11-04 09:47:42

個(gè)人信息保護(hù)法數(shù)據(jù)保護(hù)GDPR

2021-11-05 22:05:38

信息安全大數(shù)據(jù)手機(jī)

2021-11-02 08:48:16

個(gè)人信息保護(hù)法信息安全個(gè)人信息

2021-08-13 16:08:06

信息保護(hù)法信息安全網(wǎng)絡(luò)空間

2021-11-02 08:14:36

個(gè)人信息保護(hù)法信息安全個(gè)人信息

2021-11-01 22:42:04

信息安全大數(shù)據(jù)安全

2021-11-02 14:57:51

大數(shù)據(jù)信息安全科技

2022-05-17 11:52:55

金融數(shù)字化數(shù)字化轉(zhuǎn)型網(wǎng)絡(luò)安全

2020-05-28 16:28:31

網(wǎng)絡(luò)安全

2020-10-14 10:53:47

個(gè)人信息保護(hù)

2021-11-01 08:02:19

大數(shù)據(jù)信息安全網(wǎng)絡(luò)安全

2021-08-20 15:52:34

信息安全大數(shù)據(jù)安全

2021-08-21 15:06:32

大數(shù)據(jù)信息安全科技

2021-12-15 09:30:34

信息安全網(wǎng)絡(luò)安全電子商務(wù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 精品欧美一区免费观看α√ | 欧美激情在线精品一区二区三区 | 欧美中文在线 | 国产不卡一区 | 特黄特色大片免费视频观看 | 精品久久久久久久久久久久久久久久久 | 一区二区手机在线 | 亚洲网站观看 | 久久高清精品 | 色综合色综合网色综合 | 亚洲精品久久久久久久久久久久久 | 国产免费一级一级 | 色一阁| 亚洲成av | 天天弄天天操 | 久久区二区| 天天在线操 | 91天堂| 欧美日韩国产中文 | 国产精品久久久久久久久久久新郎 | 在线看h| 在线免费观看a级片 | 欧美黄色性生活视频 | 亚洲精选一区二区 | 精品日韩一区二区 | 视频一区欧美 | 另类二区 | 成人午夜免费福利视频 | 国产精品久久 | 国产一级片一区二区三区 | 99精品免费久久久久久久久日本 | 日韩一区二区三区精品 | 懂色中文一区二区三区在线视频 | 伊大人久久| 日本精品视频在线 | 我要看黄色录像一级片 | 亚洲天堂久久新 | 玖玖综合网 | 日韩欧美一区在线 | 福利二区| 久久高清|