NodeJS安全設計:好吃的草莓味糖果,只給好朋友小紅

上一篇文章中,咱們已經創建了一個有緩衝機制的文件服務器,能給客戶端響應附件類型的文件,其實,就愛蓮(iLinkIT)而言,NodeJS的模塊作到這樣也就已經能夠了,由於使用的場景就是電腦和手機之間,與部署在Internet上的服務器相比,安全性的要求是不高的。可是,咱們這一系列文章的主要目的是學習,整到如今,咱們只講了服務器對客戶端的響應,調用了response對象,可是對於客戶端提交上來的請求(request對象),沒有怎麼關注過。本文就給服務器增長一點安全特性,服務器僅僅對特定的請求才響應,返回共享的文件。如愛蓮(iLinkIT)的最終效果同樣,只有掃描指定的二維碼,才能實現文件的下載。html

老規矩,先上一給圖:node

如今咱們就來實現這樣的功能,當服務器發現客戶端的請求url是:http://localhost:8000/xiaohong時,就給客戶端響應共享的文件,其餘的請求任務,則給客戶端反饋 Hello, iLinkIT。數據庫

代碼以下:express

 1 var http = require( 'http' );
 2 var fs = require('fs');
 3 var url = require( 'url' );
 4 
 5 var file_path = "D:\\ilinkit_logo.png" ;
 6 var file_stream ;
 7 var buffer_box = [] ;
 8 var file_length = 0 ; 
 9 
10 var file_name = file_path.substr( file_path.lastIndexOf('\\')+1 );
11 
12 fs.stat( file_path , function ( err , stat ){
13             if (err) {
14                 if ('ENOENT' == err.code) {
15                     console.log( 'File does not exist...' );
16                 } else {
17                     console.log( 'Read file exception...' );
18                 }
19             } else {
20                 file_stream = fs.createReadStream( file_path );      
21                 file_stream.on( 'data' , function( chunk ){
22                     buffer_box.push( chunk ) ;
23                     file_length += chunk.length ;
24                 } ); 
25                 file_stream.on( 'end' , function(  ){
26                     console.log( "文件讀取完畢" );
27                 } );
28                 file_stream.on('error', function(err){
29                     console.log( "文件讀取失敗!" );
30                 }); 
31                 
32                 var server =http.createServer( function ( request ,response ){
33                   var h_path = url.parse( request.url ).pathname ;
34                   if( h_path === '/xiaohong' ){
35                     response.setHeader( 'Content-Type' , 'application/octet-stream' );
36                     response.setHeader( 'Content-Disposition' , 'attachment; filename=' + encodeURIComponent(file_name) );
37                     
38                     for( var buffer_index = 0 ; buffer_index<buffer_box.length ; buffer_index++ )
39                     {
40                         response.write( buffer_box[buffer_index] );
41                     }
42                     response.end();
43                    }
44                    else{
45                     response.end( 'Hello, iLinkIT' );    
46                    }
47                    
48                 } );
49                 server.listen( 8000 );
50                 console.log( 'HTTP服務器啓動中,端口:8000.....' );
51                 
52             }//end else,讀取文件沒有發生錯誤
53 });                 

關鍵代碼解析以下:瀏覽器

第3行,由於咱們要解析客戶端的請求,因此,須要加載url模塊。緩存

第33行,經過url.parse,解析出request對象中的請求路徑部分。安全

第34行~第46行,總體邏輯是,若是第33行解析出的路徑部份內容是「/xiaohong」,則給客戶端響應指定的文件,若是不是「/xiaohong」,就打一個招呼,響應'Hello, iLinkIT'。服務器

 

驗證方式以下:架構

1. 啓動服務器:打開命令行,進入js腳本所在的位置,執行:node g_ilinkit_1.jsapp

2. 打開瀏覽器,輸入:http://localhost:8000,顯示以下:

由於請求的路徑不是/xiaohong,因此顯示的是Hello,iLinkIT的內容。

3. 打開瀏覽器,輸入:http://localhost:8000/xiaohong,服務器反饋一個共享的文件附件,以下圖所示。

 

今天的文章比較簡單,就簡單回顧一下:

在HTTP服務器的響應函數中,從request對象中能夠得到客戶端請求的主機名稱、端口號以及請求路徑等等信息,而核心模塊url則提供了多種方法來解析請求中的url。

在愛蓮(iLinkIT)真實的實現中,是會生成一個時間戳做爲代碼,服務器根據傳入的時間戳參數決定如何響應,同時根據時間戳生成一個url地址的二維碼。

 request對象是一個很是重要的對象,咱們知道,在Web服務器中,請求的URL路徑不一樣,服務器的響應也不一樣,這個是Web服務器的基本框架。若是用NodeJS搭建Web服務器,也是一樣的道理,不過,託NodeJS社區的洪福,如今已經有不少現成的框架能夠選用,好比:express 框架。在express框架中,基本的思路就是服務器根據request的url地址,根據設定的‘路由規則’來調用請求的處理模塊,‘路由規則’和咱們在Java Servlet中將一個url模式映射給一個servlet處理相似。而對客戶端的響應中,服務器採用了「模板+數據」的方式,即根據業務訴求,從後臺(例如:數據庫)取得數據以後,填充到模板中,而後將頁面反饋給客戶端。固然,express框架也實現瞭如何進行身份識別等功能。若是你整明白了express框架,那麼,你會對MVC(數據-視圖-控制)架構模式會有更深入的認識。

本系列文章的主題是圍繞愛蓮(iLinkIT)來開展的,因此,若是你要用NodeJS搞Web服務器,建議找專門介紹express框架的書看一看。

最後,感謝諸位的捧場,但願能多提寶貴意見,謝謝^_^~~

 

-----------------------愛蓮(iLinkIT)系列文章------------------------------------------

 緣起愛蓮:我要的,如今就要!

愛蓮(iLinkIT)的架構與原理

碰見NodeJS:JavaScript的貴人

NodeJS服務器:一行代碼 = 一個的HTTP服務器

NodeJS文件讀取:感恩常在--抓把糖果,愉悅客人

NodeJS緩存機制:暢銷貨,就多囤一點唄

NodeJS安全設計:好吃的草莓味糖果,只給好朋友小紅

NodeJS服務器退出:完成任務,優雅退出

相關文章
相關標籤/搜索