AngularJS+RestfulAPI+BasicAuth+Python/PHP/Node.JS來實現一個最簡單的新聞管理後臺

備忘:


前言

一般來說,一個管理後臺的構建的基本流程是:(1)選擇一個開發語言->(2)選擇一種數據庫->(3)選擇一個開發輪子(framework)->(4)在輪子上搭建前端框架->(5)實現業務邏輯。 
一旦一個後臺做出來以後,有了技術積累,以後其他的項目都是克隆版本,這樣的流程的缺陷是:

  • 開發語言選型被固化 
    技術人員的招聘、團隊協作開發都必須依賴開發語言統一。
  • 業務邏輯的實現無法統一標準 
    沒有統一標準就很難書寫規範的文檔,技術人員離職很難做到順利交接,同時系統裏面的隱藏BUG很難通過標準測試發現。 

時下Web前端技術的發展風生水起,我們可以嘗試用WebAPP的思想去構架後臺,將後臺的前後端分離,前端交給AngularJS,後端交給任何一種語言框架,前後端通過標準協議接口通訊,這樣後臺構架的流程將是這樣:(1)業務流程的數據庫建模->(2)業務流程的協議文檔制定->(3)前後端工程師協作開發完成後臺


接下來我將闡述這套流程的實現原理和基本知識要點,後續文章將step-by-step去構建整套系統,需要注意的是,演示均只針對於開發環境,不會談及生產環境部署,同時只關注於系統框架的標準化,對於使用到的各種語言技術結構可能會不太標準,請諒解。

基礎知識

  • CRUD 
    後臺的最終目的就是針對數據庫的操作,而操作歸納下來無非就是 Create(新增),Read(讀取),Update(更新),Delete(刪除),這就是CRUD的意思,參見維基的解釋
  • Restful 
    前後端分離,我們需要將CRUD的接口通過標準協議(WebAPI)來實現,Restful就是爲這個協議而生的,參見老外的解釋
HTTP請求 CRUD 返回狀態位
POST Create 201
GET Read 200
PUT Update 200
DELETE Delete 200
  • Authentication 
    用戶的驗證服務是任何一個後臺都必備的功能,現在WebAPI驗證服務國際化的標準很多,我分析了一下各種開發語言輪子對於這些標準的支持力度,整理了用得比較多的3個標準: 
    1. Session 
      這是常規後臺使用的驗證方式,後臺提供登錄/登出的接口,同時保持一個會話在服務端,後續的web請求都是基於該會話的存在,優點是對於後端來說實現比較簡單,比較容易實現對於用戶權限的控制,缺點是用到了Cookie,對於基於RestfulAPI實現的後臺系統來說,原則上是不允許使用到session和cookie的,所以有些固執的輪子例如(php-yii)就明確表示不支持Yii官方文檔
    2. HTTP Basic Auth 
      參見維基的解釋,每一個web請求頭中,都將Username/Password通過base64加密,後端解密驗證,優點是簡單,基本每個輪子都支持,缺點是沒有登錄/登出,而且每次請求都會把密碼傳過去,總感覺安全性有問題(其實沒什麼問題),所以生產環境一般很少用,測試環境用用挺好。這裏寫圖片描述
    3. Oauth 2 
      這是一個完美的驗證方案,參見官方介紹,大概的原理是客戶端首先向驗證服務器申請一個令牌(token),然後通過token登錄到後臺,後臺與驗證服務器通訊驗證token合法性、時效性、權限。目前廣泛被應用於開放平臺的認證服務中,而阿里雲後臺是採用AngularJS書寫的,他們的驗證服務就是採用Oauth2。優點是驗證和後臺分離、各輪子都支持,缺點是實現複雜這裏寫圖片描述
  • AngularJS

    AngularJS(後文將簡稱ng)是目前比較流行的Web前端框架,它的最大特點就是數據綁定這裏寫圖片描述 
    由於這個特點,用它來做後臺的前端框架是最合適的,model將數據從後端取下來,通過數據綁定渲染到view,再通過bootstrap裝飾一下template,一個高大上的後臺系統就能快速實現。 
    我們這裏使用的是ng1.3,按照官方說明,1.3開始已經不再兼容IE8

Note: AngularJS 1.3 has dropped support for IE8. Read more about it on our blog. AngularJS 1.2 will continue to support IE8, but the core team does not plan to spend time addressing issues specific to IE8 or earlier.

  • CORS 
    Cross-Origin Resource Sharing(跨域資源共享),我們用Ajax發送WEB請求,只要是跨域訪問就會遇到這個問題,解決方法是後端在HTTP響應頭裏面加入Access-Control-Allow-Origin等標籤,一般輪子都會有開發者提供此功能插件。 
    順帶談談jsonp,在CORS沒有誕生之前,發明這個技術來解決跨域問題的程序員真是個天才!客戶端書寫一個callback函數,ajax請求時將這個callback函數名帶個服務器,服務器返回數據時,順帶去執行這個callback,由於是服務器主動去執行這個callback,就繞開了跨域問題。目前jsonp已經逐漸廢棄了,一個是因爲非官方出品,不是所有瀏覽器都支持,另一個原因jsonp只能解決GET請求的跨域。

  • Postman 
    訪問官方網站,postman是一個chrome瀏覽器的插件,可以很方便的測試RestfulAPI 
    這裏寫圖片描述

實現原理

AngularJS+RestfulAPI+BasicAuth+Python/PHP/Node.JS來實現一個最簡單的新聞管理後臺。 
業務要求:提供基本的後臺登錄/登出、實現新聞的CRUD、分頁、搜索。

數據庫建模

列名 字段 含義 說明
id int ID PK
title varchar(100) 標題 NN
content text 內容 N
create_time datetime 創建時間 NN

制定協議

URI 請求方式 返回 功能
/auth/info GET {userid:int,username:string} 用戶驗證
/news/ POST NULL 新聞-創建
/news/?page=int&search=str GET 見下文備註 新聞列表-讀取
/news/:id/ GET {id:int,title:str,content:str,create_time:str} 新聞-讀取
/news/:id/ PUT NULL 新聞-更新
/news/:id/ DELETE NULL 新聞-刪除
/news/deletes/?ids=int,int DELETE NULL 多條新聞-刪除

備註:新聞列表-讀取 
請求參數:page顯示第幾頁,search搜索關鍵字 
返回數據:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">{
    total_count:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>,  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//總記錄數</span>
    page_count:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>,   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//總頁數</span>
    next:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">bool</span>,        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//是否有下頁</span>
    previous:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">bool</span>,    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//是否有上頁</span>
    results:[],       <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//結果集</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

後臺實現 
效果圖 
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

源碼演示

源碼下載地址:http://pan.baidu.com/s/1qXic6IC 
源碼是跨平臺的,這裏選用的演示環境是Win7

  • 前端 
    1) 安裝IIS; 
    2) 指定虛擬目錄admin到client/; 
    3) 訪問http://127.0.0.1/admin/即可(注意,如果使用IE瀏覽器,要IE9以上內核)

  • 後端-Python 
    1) 安裝soft/python-2.7.3.msi; 
    2) 安裝soft/Django-1.9.1.tar.gz (解壓以後命令行執行 setup.py install) 
    3) 安裝soft/django-rest-framework-master.zip (解壓以後命令行執行 setup.py install) 
    4) 安裝soft/django-cors-headers-master.zip (解壓以後命令行執行 setup.py install) 
    5) server-python目錄下執行 manage.py runserver

  • 後端-PHP 
    1) 安裝soft/vcredist_x64.exe (php要求的vc11運行環境) 
    2) 安裝soft/php-5.6.16-Win32-VC11-x64.zip (解壓即可) 
    3) 將php目錄加入到系統環境變量Path中 
    4) server-php目錄下執行 php -S 127.0.0.1:8000

    注意,該PHP壓縮包中的php.ini我做過了一些修改: 
    extension=php_pdo_sqlite.dll #增加sqlite支持 
    always_populate_raw_post_data = -1 #新版PHP-win對於POST處理的舊函數有過期警告,會導致CORS中斷,這裏禁用該警告,linux下PHP5.6無此問題 
    date.timezone = ‘Asia/Shanghai’ #糾正時區

  • 後端-Node.js 
    1) 安裝soft/node-v5.0.0-x64.msi 
    2) server-nodejs目錄下執行如下指令

    <code class="hljs markdown has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-blockquote" style="box-sizing: border-box;">> set PORT=8000</span>
    <span class="hljs-blockquote" style="box-sizing: border-box;">> npm start</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

前後端具體書寫流程參見:

管理後臺-後端-Python篇 
管理後臺-後端-PHP篇 
管理後臺-後端-Node.js篇 
管理後臺-前端-AngularJS



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章