溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Django怎么部署

發(fā)布時間:2022-01-12 09:35:26 來源:億速云 閱讀:195 作者:iii 欄目:網(wǎng)絡(luò)安全

這篇“Django怎么部署”文章的知識點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Django怎么部署”文章吧。

PART 1. 安全第一

修復(fù)漏洞的最佳時機(jī)便是開發(fā)的時候。

1.1 CSRF TOKEN

CSRF TOKEN是Django安全體系中的一項非常重要的安全措施。但是很多情況下,一些剛剛接觸Django的同學(xué)會發(fā)現(xiàn)自己好不容易寫出來的表單,在POST的時候報錯了,經(jīng)過一番查找發(fā)現(xiàn)是CSRF TOKEN的問題,然后按照網(wǎng)上的方法三下五除二將settings.py中的CSRF TOKEN配置全部移除了,代碼正常跑起來了。熟不知這種操作將極大的影響網(wǎng)站的安全性,且提高了后期修補(bǔ)漏洞的成本;而在開發(fā)階段消滅安全問題,是成本最低的時候。

關(guān)于CSRF TOKEN的相關(guān)內(nèi)容,官方文檔上有十分詳細(xì)的說明,具體用法這里不再闡述了。這里推薦一種比較方便的用法,在開發(fā)的時候?qū)﹂_發(fā)人員的感知較小,不用特別去關(guān)心Token是否已經(jīng)發(fā)送成功了。

在總的父模板頁面中添加{% csrf_token %},并且在<script>部分進(jìn)行如下設(shè)置:

Django怎么部署

這樣所有通過JQuery中的的AJAX發(fā)起的非GET|HEAD|OPTIONS|TRACE請求都會自動包含CSRF TOKEN(獲取CSRF TOKEN的部分代碼未列出),如果使用的是其他HTTP庫或Fetch,進(jìn)行對應(yīng)的設(shè)置即可。

1.2 API安全設(shè)計

某些情況下,我們的Web服務(wù)還會對外提供一些API服務(wù),供其他系統(tǒng)調(diào)用,對于這些API接口,CSRF是一定要關(guān)閉的,不然根本無法正常使用。除此之外,我們還應(yīng)當(dāng)做一些其他的安全措施,防止API接口被濫用。除了正常的傳遞參數(shù)外,我們應(yīng)當(dāng)保證這些參數(shù)不被中間人篡改,并且只允許有權(quán)限的人調(diào)用對應(yīng)的接口,為此我們需要額外引入幾個傳遞的參數(shù):timestamp, sign, access_key, access_token。

access_key和access_token,這是一對參數(shù)。access_key相當(dāng)于標(biāo)識調(diào)用方是誰,access_token則是相當(dāng)于調(diào)用方的秘鑰,access_token內(nèi)容不應(yīng)該能被簡單的預(yù)測到,而access_key可以為了方便記憶選擇較為簡單的字符串。只有當(dāng)兩個參數(shù)匹配后,才認(rèn)為本次API的調(diào)用是合法的。

timestamp時間戳,根據(jù)自己的業(yè)務(wù)情況選擇精確到秒或是毫秒。添加時間戳主要是為了防止本次調(diào)用被重放攻擊,服務(wù)端應(yīng)當(dāng)校驗客戶端傳遞的時間戳是否在一個時間范圍內(nèi),超時的時間戳都應(yīng)當(dāng)被認(rèn)為是非法的請求。但是時間戳在重放的時候還是有被篡改的風(fēng)險,所以就需要引入下一個參數(shù)sign來保證參數(shù)的真實性。

sign是所有參數(shù)的簽名值,是所有參數(shù)值參與hash計算產(chǎn)生的,參數(shù)每變動一點(diǎn),sign都需要重新生成,借此保證參數(shù)的真實性。常用的一套算法是:根據(jù)參數(shù)key的字母序,將參數(shù)value進(jìn)行排序,并且使用特定的分隔符連接起所有的參數(shù),然后進(jìn)行hash計算,并將sign參數(shù)一同傳遞給服務(wù)端。舉個例子,現(xiàn)有參數(shù)ak=2222&at=1111&amptimestamp=3333&key1=aaa,根據(jù)字母序排序完成后為22221111aaa3333,加入分隔符(|)后為2222(|)1111(|)aaa(|)3333,然后將這個字符串計算sha1,生成sign值。用Python代碼寫的話比較簡單:

Django怎么部署

1.3 一些雜項

除了上面兩個比較重要的點(diǎn)之外,還有一些地方需要額外關(guān)注一下。

在生產(chǎn)環(huán)境關(guān)閉DEBUG模式;

不要將settings.py添加到版本管理中,并且保護(hù)好SECRET_KEY;

設(shè)置好ALLOWED_HOSTS;

盡可能的使用Django提供的ORM,避免通過.raw()等方法直接執(zhí)行SQL語句,如果無法避免,一定要將參數(shù)正確轉(zhuǎn)義以避免出現(xiàn)SQL注入漏洞;

盡可能的禁用Django Admin,如果一定需要使用,請修改掉默認(rèn)的Admin URL;

PART 2. 如何部署

從git上拉下代碼,使用pip安裝項目依賴,通過manage.py運(yùn)行服務(wù),這一切看起來很美好,可是你真的打算在生產(chǎn)環(huán)境中這樣做嗎?

2.1 隔離環(huán)境

一般情況下,我們的服務(wù)器上都只會有一個Python環(huán)境,部署的時候一般都是通過pip來安裝項目所需要的依賴,這些包都會被安裝到全局的site-packages目錄中。

但是當(dāng)我們部署多個項目的時候,這種安裝依賴的方式很容易出現(xiàn)依賴沖突。舉個簡單的例子,我們現(xiàn)在有Project-A和Project-B兩個項目,A和B都依賴第三方包third-A的不同版本,當(dāng)我們通過pip install -r requirements-a.txt的時候,依賴third-A被安裝到了全局的Python環(huán)境中,當(dāng)我們再次安裝pip install -r requirements-b.txt的時候,也會再次安裝third-A,這個時候,如果兩個項目依賴的版本不一致,譬如A項目需要1.0版本,而B項目需要2.0版本,就會產(chǎn)生依賴沖突,進(jìn)而導(dǎo)致安裝依賴失敗。

那么如何解決這個問題呢?我們很容易想到的就是,如果我們有多個互不相干的隔離環(huán)境,每個項目部署在一個獨(dú)立的環(huán)境中,那么這個問題就迎刃而解了。virtualenv正是為了解決這個問題而誕生的,它可以為每個項目創(chuàng)建一個單獨(dú)的運(yùn)行環(huán)境,從而避免依賴沖突的問題。

2.2 版本管理

前面我們知道了如何創(chuàng)建隔離環(huán)境并且在不同的環(huán)境中部署不同的項目,但是這里有個問題,所有環(huán)境使用的Python版本是一樣的。如果恰好你需要部署多個不同版本的Python項目,例如Python2.7(我知道這個版本即將不維護(hù)了,但是我在這里舉個例子)、Python3.6和Jython項目,一個一個安裝就顯得有些復(fù)雜,甚至編譯安裝的時候一不小心少了某個編譯參數(shù)而需要重新編譯,都在某種程度上加大了部署工作量。

我們可以通過使用pyenv來管理多個Python版本的問題,進(jìn)一步通過pyenv的插件pyenv-virtualenv來管理多Python版本、多虛擬環(huán)境的問題。

2.3 網(wǎng)關(guān)接口

當(dāng)我們解決了各種環(huán)境的問題后,是時候來考慮如何將項目跑起來了,如果你想的是python manage.py runserver 0.0.0.0:80,那就有點(diǎn)太過于簡單了。

Django中已經(jīng)內(nèi)置了一個簡單的WSGI實現(xiàn)來供我們通過上述方式啟動Web服務(wù),如果你只是想調(diào)試或者只提供服務(wù)給幾個人用的小程序,那也不失為一種可選擇的方案,雖然這種方案看上去并不是那么優(yōu)雅。

如果你真的想將應(yīng)用部署到實際的生產(chǎn)環(huán)境中,那么你還需要一個高性能的WSGI Server,而不是django提供的簡單的WSGI Server。Gunicorn和uWSGI兩種都是比較主流的WSGI Server,根據(jù)實際部署環(huán)境,從中選擇一個就好。

不過我個人比較偏向于Gunicorn,雖然在眾多的性能測試中uWSGI都占了上風(fēng),選擇Gunicorn的理由是它與uWSGI相比十分簡單,沒有非常復(fù)雜的極少用到的功能,并且uWSGI中的一些功能已經(jīng)逐步被Nginx所支持,且Gunicorn配置起來也較為簡單方便。順帶一提,如果你在Windows上部署,你可能需要使用Apache+mod_wsgi。

2.4 反向代理

當(dāng)我們的WSGI Server啟動就緒后,就要考慮一下反向代理的問題了,之所以前面再擋一層Nginx進(jìn)行反向代理,有以下幾點(diǎn)原因:

需要Nginx來處理靜態(tài)資源。如果你將Django的DEBUG模式設(shè)置為False,就會發(fā)現(xiàn)很多CSS以及JS等靜態(tài)資源加載不到了,這是因為Django并不會主動去處理這些請求,這些都需要Nginx來幫忙處理;

通過Nginx來進(jìn)行多個backend的負(fù)載均衡。如果你的服務(wù)部署在多臺服務(wù)器上,或是進(jìn)行了一主一備的部署,這些都可以通過在Nginx上進(jìn)行簡單的設(shè)置來實現(xiàn);

直接將uWSGI或Gunicorn暴露出來存在一定的安全隱患,使用Nginx處理HTTP的問題會更加方便;

除此之外,還有一些理由就不在此列舉了,還是上面的那句話,如果你的服務(wù)很簡單,只有幾個人訪問,是不需要做這么復(fù)雜的設(shè)置的。

2.5 進(jìn)程守護(hù)

到現(xiàn)在為止,我們的服務(wù)已經(jīng)部署成功了,并且可以開始提供正常的服務(wù)了。但是我們少考慮了一點(diǎn),如果我們的Django不幸因為一些未知的原因退出了,那么我們的Web服務(wù)就會變成502了。為了保證服務(wù)的穩(wěn)定性,我們需要對Django進(jìn)程進(jìn)行守護(hù),當(dāng)其出現(xiàn)未知問題而導(dǎo)致異常退出的時候,需要自動將需要的進(jìn)程拉起來。

我們可以使用supervisor來守護(hù)Django進(jìn)程,保證其穩(wěn)定存活。但是有一點(diǎn)需要注意,小心不要出現(xiàn)Supervisord的遠(yuǎn)程命令執(zhí)行漏洞,從而造成更大的事故。

PART 3. 后臺服務(wù)

通常來講,如果想啟動后臺服務(wù)的話,celery是一個萬能的選擇,但是很多時候我們并不想引入這么重的依賴,就需要自己想辦法來啟動后臺服務(wù)了。

一個簡單的方法就是做成manage.py的command,通過./manage.py runcommand的方式來啟動我們的后臺服務(wù),并且通過編寫shell腳本控制服務(wù)的啟動與停止,或者通過supervisor進(jìn)行管理。

如果你想讓后臺進(jìn)程隨著Web服務(wù)同時啟動和停止,那么放到wsgi.py中是個不錯的選擇,在wsgi.py中初始化相關(guān)的后臺服務(wù),并且啟動。但是這樣的做法不夠靈活,當(dāng)需要單獨(dú)更新Web服務(wù)或后臺服務(wù)時,需要將二者全部重啟,而采用第一種方式的情況下可以單獨(dú)更新其中的某個服務(wù)。

以上就是關(guān)于“Django怎么部署”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI