文章及代碼比較基礎,適合初、中級人員,高手略過
閱讀此篇文章你可以:
獲取一個Django實現增刪改查的案例源碼
瞭解數據加密的使用場景和方法以及如何在Python3中使用
背景介紹
DBA需要維護一張密碼錶,主要記錄數據庫中創建的賬號密碼信息,大概如下:
目前的維護方式還是最傳統的Excel,一個人更新給多個人同步,Excel設置密碼以保證安全性,原始且效率低下,既然我們已經上線了overmind數據庫運維繫統,何不在系統裏邊集成這個功能呢?
技術實現
簡單分析就可以知道,我們要實現的功能如下:
1.最基礎的表單增刪改查
2.涉及到密碼存儲需要加密
update_or_create
表單增刪改查大家應該都比較熟悉了,實現方式有很多,我們採用了最簡單的view方法來實現,詳細內容查看源代碼。
代碼中用到了Django的一個QuerySet API可能部分人沒有用過update_or_create,這裏詳細介紹下
update_or_create(defaults=None, **kwargs)
看到方法的命名大概也能猜出來這個方法的主要作用就是更新或者創建model數據,那麼究竟什麼情況下更新?什麼情況下創建呢?主要根據傳入的**kwargs來判斷,defaults爲要更新的數據。一句話概括爲filter kwargs,create/update defaults
例如對於一張用戶表我們要判斷username爲devops,且email爲[email protected]的用戶是否存在,如果不存在則創建這個用戶,且設置用戶的site爲https://ops-coffee.cn,如果存在則更新這個用戶的site爲https://ops-coffee.cn,則可以這樣寫
object, created = User.objects.update_or_create(
username='devops',
email='[email protected]',
defaults={
'username':'devops',
'email':'[email protected]',
'site':'https://ops-coffee.cn'
}
)
額,上邊的例子是不是有點複雜了,拿我們項目裏邊的實例爲例,就是判斷id是否存在,如果存在則更新,如果不存在則創建
object, created = Table.objects.update_or_create(
id=postdata.get('id'),
defaults=postdata
)
update_or_create方法返回結果爲一個元組(object, created),object爲新建或者更新的對象,created爲一個布爾值,表示是新建還是更新,True爲新建
密碼加密
對於密碼加密,我們知道加密算法有很多,究竟哪種適合我們呢?
看一下我們的需求,存儲的時候要加密存儲,但也要能對加密後的數據進行解密以獲取原始密碼,那麼就要求加密算法既支持加密,也支持解密,對於md5這種只支持加密的單向算法就不能選擇了,在支持加解密的算法中應用最爲廣泛的當屬RSA了,我們最終也選擇了RSA,其實單單對於這個場景來說用3DES之類的對稱加密就夠了,速度也會快很多,但是考慮到系統裏邊有其他的加密需求選擇RSA能滿足更多情景。
RSA加密算法非常複雜,感興趣的可以查詢專業資料,RSA需要一對祕鑰稱爲公鑰和私鑰,公鑰可以對字符串進行加密生成加密字符串,拿私鑰可以將加密字符串還原。
python3中RSA的使用
生成RSA祕鑰對代碼
from Cryptodome.PublicKey import RSA
def create_rsa_key():
'''生成RSA祕鑰對'''
try:
# 選擇祕鑰位數,位數越高越安全,同時加密速度也越慢
key = RSA.generate(2048)
encrypted_key = key.exportKey(pkcs=8)
public_key = key.publickey().exportKey().decode('utf-8')
private_key = encrypted_key.decode('utf-8')
return {'state': 1, 'message': {'public_key': public_key, 'private_key': private_key}}
except Exception as err:
return {'state': 0, 'message': str(err)}
if __name__ == '__main__':
print(create_rsa_key())
執行腳本生成RSA祕鑰對,將RSA祕鑰對配置在加解密的代碼中
RSA加密解密代碼
import binascii
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_v1_5
class RsaCrypto(www.feifanyule.cn):
'''RSA 加解密'''
def __init__(self):
self.private_key = '''-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDLetN9MfsVWZj2
K+i1vPQqeDKb8Fe52pHKvRtQggTF+x3YRCyk7UNQ27VupohM8t+Qzi2Zm3GnZY5X
H7W8UGLnI1X1ykpWOWVueP3KCA7DCtswDp5hkJgHzPPZC/DlFh0uCpAmUkgHP7WU
XRZoR9mmcVOdWN9c+NWS0JA6cwHSI+J78Edb1lfef5YOwseL2GiOmBiJ7THYfjrw
FwGQaZVjhsp3Pkt7Yt/Huc5NU234wA9j+TFFnubpOrE9mFT8qCkhFhWIEcNsuTqD
DDI9BX0lLaEEn+vg9cnEZ97VgdQQG2D6Ozw4Gldpfoq1XB6BqXg+YsCvyD/h/4QD
LpejZy/VAgMBAAECggEADJkoj6omNevb459Tri+VHS1fUiEEXXZ3QQqKWWa4wu/0
U2030mek8P8EHGYP2avOmcRE4IDWUvCfv9cvxQljxj8oKwABBZZSKGUyBBiRnr6E
/v8OC/5hhgIeNZm0ADW+osN2qgNoKu1lNwVjG3EaEbXB4TkdGJWI1lPhdNelYjby
7/4vnXO7yplSFlDLiqjmEV9Vva3Jf3N3vf92ZfUJg6NHklYDlP+L4unNtS++HKtv
C3TWSz0esVrK67t4Vut+RdKrSQzzWkPAqNwktUavQq6Nb+KMrf9tsQujPZaXkEUn
LUwtVNwhT3BiyPswHN1ycjlP3lN391rnawDQc751dQKBgQDZSFBq1JaGm4zK2YHm
BbxCJ++6l1Qmu9yhk/zic1M/oGoFRdzkeWrYsxhLupp+4PjcCPEiZqivSeJXsFVO
diSjWsBkfO51HRuEzRE2Z/tiTRzJsGAcrBsWwBYNZR/PADG7MEYhIYH0p6Jp3jrq
pNs0f5Gz8XToPi2TQXmRyAltFwKBgQDvvOFlJFfx1ld2wLuZ0w1yMpUoyFYCWSh+
ylREFETod8ufbQxRzvvSA3gFO+xwYZoA+Wq/TyGrfVnN9m4R1goPsQjsuUYQeAIi
MBKmG5znTAmu8dQ5wLKtb10CV0MuFGOSv8xvlccKepY7IDtxOaO410o4PFEjAziU
90b8RiRV8wKBgHDsUD71NTXH6agS2pu9J1YKg2Cp/SYURFoFG0xlO0K6D9+lq2Ni
ZtEwYtQYqup96VgRnaCPUeOntmZ0UiFw7SGorIyNETD0a7TdDrED4XX5NZjsfUbp
ezqbodpcT+e45h+uuwPE8lFAPfxfbqc7/ www.quwanyule157.com mCOXB70whlhFzaMtK27FIsJAoGAVtTJ
qnF8bPpeWYO7Lx7TOu55Ofk9tcIHOc0csj/JKY3iMY80rBjU+p8JBJRMsfOX7Qxp
jnshzdQsB75e5ZTptf9AJUWBzAs7cpiI2KMdtGTFCRlL7dMOpGS2gleK3JDD8+4G
JNBR9EisSyQEg6EF3LgViMLH/G95OfNKQatCE+MCgYEAhRIuEMaL2idD9NKOVdgC
fuSbiP5G69IBVD4uoDYFPQJjxqVOg3pORa8+cJTe+ZFaCkTGV3112eM5Vtm4Vd9Q
pOh7VgJP1l3puZnUoSWGoWansx6aKok5FwuUrZWPjqr/Zrre8XXJyaiR520tuf0i
StMfNAsijJgi2pq2PTMovhE=
-----END PRIVATE KEY-----'''
self.public_key = '''-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy3rTfTH7FVmY9ivotbz0
Kngym/BXudqRyr0bUIIExfsd2EQspO1DUNu1bqaITPLfkM4tmZtxp2WOVx+1vFBi
5yNV9cpKVjllbnj9yggOwwrbMA6eYZCYB8zz2Qvw5RYdLgqQJlJIBz+1lF0WaEfZ
pnFTnVjfXPjVktCQOnMB0iPie/BHW9ZX3n+WDsLHi9hojpgYie0x2H468BcBkGmV
Y4bKdz5Le2Lfx7nOTVNt+MAPY/kxRZ7m6TqxPZhU/KgpIRYViBHDbLk6gwwyPQV9
JS2hBJ/r4PXJxGfe1YHUEBtg+js8OBpXaX6KtVwegal4PmLAr8g/4f+EAy6Xo2cv
1QIDAQAB
-----END PUBLIC KEY-----'''
def encrypt(self, plaintext):
'''加密方法'''
try:
recipient_key = RSA.import_key(self.public_key)
cipher_rsa = PKCS1_v1_5.new(recipient_key)
en_data =www.michenggw.com cipher_rsa.encrypt(plaintext.encode('utf-8'))
hex_data = binascii.hexlify(en_data).decode('utf-8')
return {'state': 1, 'message'www.mingcheng178.com/: hex_data}
except Exception as err:
return {'state': 0, 'message': str(err)}
def decrypt(self, hex_data):
'''解密方法'''
try:
private_key = RSA.import_key(self.private_key)
cipher_rsa = PKCS1_v1_5.new(private_key)
en_data = binascii.unhexlify(hex_data.encode('utf-8'))
data = cipher_rsa.decrypt(en_data, None).decode('utf-8')
return {'state': 1, 'message': data}
except Exception as err:
return {'state': 0, 'message': str(err)}
if __name__ == '__main__':
print(RsaCrypto().encrypt())
對原始密碼加密
>>> _t = RsaCrypto(www.gcyL157.com).encrypt('ops_coffee.cn')
>>> print(_t)
{'state': 1, www.gcyl158.com'message': 'ae3e52eede23a7c9dd348244f0ae90b06c6773e9fecb2383f8195c50e6032742fb793423d75082db9a325b091d3e02351cd04157c68a64a5c130c0eaf7de1396d8993f0d649d1f3c1004119aa221daefca52215a235fb316af313ef64479957264012be20a1d54987386a3f29ae2fe80e147e7eeb770803045cab0d979aa6d5b88c39058f8fba7f6bf06bc436be59a19ccb72ac2813d809132203a64020bbe3c0c3df74befa8b18fb4782e34daff8f6e33e4b45cbe1b2db2be2c3e38a1c9e0e314178ed36a53960017fd9af5f27d99c5e5e0a8d384ac83156598788334248507ac1498fe44b1fb7e3b43e44a8bf3fc189076b16efef2c0f0a86d7faa0
53bbe24'}
獲取加密後的字符串
>>> hex_data = _t.get(www.mhylpt.com'message')
>>> print(hex_data)
ae3e52eede23a7c9dd348244f0ae90b06c6773e9fecb2383f8195c50e6032742fb793423d75082db9a325b091d3e02351cd04157c68a64a5c130c0eaf7de1396d8993f0d649d1f3c1004119aa221daefca52215a235fb316af313ef64479957264012be20a1d54987386a3f29ae2fe80e147e7eeb770803045cab0d979aa6d5b88c39058f8fba7f6bf06bc436be59a19ccb72ac2813d809132203a64020bbe3c0c3df74befa8b18fb4782e34daff8f6e33e4b45cbe1b2db2be2c3e38a1c9e0e314178ed36a53960017fd9af5f27d99c5e5e0a8d384ac83156598788334248507ac1498fe44b1fb7e3b43e44a8bf3fc189076b16efef2c0f0a86d7faa053bbe24
對加密後的字符串進行解密
>>> _x = RsaCrypto().decrypt(hex_data)
>>> print(_x)
{'state': 1, 'message': 'ops_coffee.cn'}
頁面展示
列表頁:列表頁使用了datatables插件方便展示,且使用了Django的模板引擎直接渲染
添加:一個簡單的功能,這裏就在當前頁面彈出model彈出框的方式來展現
編輯:添加、編輯、刪除都採用前後端分離,ajax異步json數據交互
查看原始密碼:實際上是有權限管理的,並非所有用戶都能查看原始密碼
源碼地址
aHR0cHM6Ly9naXRodWIuY29tL29wcy1jb2ZmZWUvZGVtby90cmVlL21hc3Rlci9wYXNzd29yZA==
如果你覺得文章對你有幫助,請轉發分享給更多的人。如果你覺得讀的不盡興,推薦閱讀以下文章:
Django+Echarts畫圖實例
Django model轉字典的幾種方法
Django開發密碼管理表實例【附源碼】
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
Django开发企业实战 面向就业/升职(中高级教程)
wy53780
2020-04-23 14:16:39
Django入门到进阶-适合Python小白的系统课程
wy53780
2020-04-23 14:10:58
Django-ModleForm
jedi911
2019-02-23 00:42:19
Python Day23 stark組件1
jedi911
2019-02-23 00:42:19
stark組件3_filter過濾
jedi911
2019-02-23 00:42:19
Django-自定義分頁
jedi911
2019-02-23 00:42:19
基於Django的rbac權限驗證
jedi911
2019-02-23 00:42:19
stark組件5_擴展url
jedi911
2019-02-23 00:42:19
Python Day24 stark組件2
jedi911
2019-02-23 00:42:19
stark組件4_pop功能
jedi911
2019-02-23 00:41:26
Django學習-----Django開發流程
huanjie6
2019-02-23 00:29:22
Django1_簡述及第一個項目搭建
易水寒月
2019-02-23 00:13:10
Django+Nginx+Uwsgi架構部署,新建個app添加web(二)
Hellvenus
2019-02-23 00:12:47
Django Form表單對象
zhlccna
2019-02-23 00:04:49
使用django運行django-admin.py無法創建網站
殷巖泉
2019-02-22 23:27:51