資料庫(六)
前言
本篇部落格學習 mysql 的使用者管理和使用 python 操作 mysql 的一個模組 pymysql。
mysql 使用者管理
因為資料安全對於網際網路公司來說是最重要的,不可能隨便分配 root 賬戶,應該按照不同開發崗位分配不同的賬戶和許可權。
使用者管理相關表
mysql> use mysql; mysql> show tables;
使用者對資料庫的許可權順序
mysql 將與使用者相關的資料放在 mysql庫中,
user->db->tables_priv->columns_priv
如果使用者擁有對所有庫的訪問權,則儲存在 user 中;
如果使用者擁有對部分庫的使用權,則儲存在 db 中;
如果使用者擁有對部分表的使用權,則儲存在 tables_priv 中;
如果使用者擁有對錶中某些欄位的使用權,則儲存在 columns_priv 中。
使用者授權設定
建立新賬戶
mysql> create user 使用者名稱@ip identified by '密碼';
mysql> create user [email protected] identified by '123';
建立成功後會在 user 表中檢視到:
mysql> select * from user\G;
這樣建立的賬戶是沒有任何許可權的,可以看出關於許可權欄位的值全為 N,接下來需要給 musibii 賬號分配許可權了。
授予使用者最高許可權
mysql> grant all on *.* to [email protected] identified by '123';
如果 musibii 賬號不存在,那麼會在授予許可權的時候自動建立賬號。
現在檢視一下 musibii 賬號的許可權關係:
授予授予許可權
現在除了 grant_priv 許可權其他許可權都有了,這個許可權是授權許可權。通過 root 賬戶授予:
mysql> grant all on *.* to [email protected] identified by '123' with grant option;
現在可以說這個賬號就是一個 root 賬戶,但是隻能在本機登陸。
授予在任何地方登陸許可權
mysql> grant all on *.* to musibii@'%' identified by '123';
現在 host 欄位對應的值變為了%,意味著可以在任何主機登陸該資料庫了。
設定只能訪問某個庫
mysql> grant all on day46 to eureka@'%' identified by '123';
這樣設定的使用者許可權資訊儲存在 db 中,但是不知道為什麼在 db 中沒有賬戶資訊。。。
設定能能訪問某個庫中的某個表
mysql> grant all on day46.emp to thales@'%' identified by '123';
設定只能增刪查改許可權
mysql> grant select(name) on day46.emp to thales@'%' identified by '123';
這樣 thales 使用者就只能對 emp 表中的 name 欄位進行查詢操作了。
使用者收權設定
收回某個賬號的所有許可權
mysql> revoke all privileges [column] on db.table from user@'host';
mysql> revoke all privileges on *.* from musibii@'127.0.0.1';
查詢 user 表中的許可權資訊,發現除了授權許可權其他許可權都沒有了:
不過在修改許可權之後需要重新整理許可權表:
mysql> flush privileges;
注意:如何授予許可權就應該如何收回許可權,因為不同的許可權儲存在不同的表中
刪除使用者
mysql> drop user 使用者名稱@主機;
當你在雲伺服器部署了 mysql 環境時,你的程式無法直接連擊伺服器,需要授予在任意一臺電腦登陸的許可權
mysql> grant all on *.* to 使用者名稱@'%' identified by 密碼 with grant option;
pymysql
pymysql 連線資料庫
import pymysql conn = pymysql.connect( host='127.0.0.1', port=3306, user='root', password='123', database='day46', charset='utf8')
操作資料庫
cursor 遊標物件,負責執行 sql 語句,獲取返回的資料
cursor = conn.cursor() sql = 'select *from emp' res = cursor.execute(sql) # 返回值是本次查詢的記錄條數 # 獲取一條記錄 print(cursor.fetchone()) # 接著獲取 print(cursor.fetchone()) # 提取所有結果 print(cursor.fetchall())
print(fetchamany(3))
執行結果
((3, '關羽', '男', '市場', '員工', 4000.0), (4, '孫權', '男', '行政', '總監', 6000.0), (5, '周瑜', '男', '行政', '員工', 5000.0))
引數是指定獲取的資料條數。
控制遊標位置
cursor.scroll(1,mode='relative) # 遊標從當前位置往後移動一條記錄 cursor.scroll(1,mode='absolute') # 遊標從開始位置往後移動一條記錄
獲取結果使用字典表示
指定使用字典型別的遊標,預設是元祖型別
cursor = conn.cursor(pymysql.cursor.DictCursor)
在 python 使用程式碼執行了增刪查改後只是在記憶體中修改了值,想要修改資料庫中的值需要提交操作
conn.commit()
這樣修改的值才會改變。
sql 注入
import pymysql conn = pymysql.connect( host='127.0.0.1', port=3306, user='root', password='password', database='day46', charset='utf8') cursor = conn.cursor(pymysql.cursors.DictCursor) name = input('使用者名稱') pwd = input('密碼') sql = 'select * from user where name = "%s" and pwd = "%s"' % (name, password) res = cursor.execute(sql) if res: print('登陸成功') else: print('登陸失敗')
注入寫法
避免方式:
- 再輸入時加上正則判斷,不允許輸入與 sql 相關的關鍵詞。這種方式無法避免代理伺服器發起的攻擊;
- 2.在服務端,執行 sql 前進行判斷。
pymysql 中已經做了處理,只要將引數的拼接交給 mysql 來完成就能夠避免攻擊。
程式碼實現
name = input('使用者名稱') pwd = input('密碼') sql = 'select * from user where name = %s and password = %s' res = cursor.execute(sql, (name,pwd)) # 這樣執行 sql 語句就可以避免攻擊。