1.1. 最簡單的MySql權限
最簡單也是最高效的,如果解決新手們刪庫跑路的問題其實也是很簡單的,對於正式庫只給一個增刪改查的權限,或者只給一個查詢權限(是不是就解決了刪庫的可能性?)
使用Root用戶,執行
grant SELECT on mall.* TO 'dev'@'192.168.244.%' IDENTIFIED BY '123' WITH GRANT OPTION;
很簡單的一句sql,創建了一個dev的用戶,密碼為123,僅僅運行在網段為192.168.0.*的網段進行查詢操作。
再執行一條命令
show grants for 'dev'@'192.168.244.%'
不錯,可以鏈接,也可以執行select,這個時候還想刪庫?做夢吧~
1.2. 深入研究下MySQL權限
1.2.1. 用戶標識是什么
上面一句簡單的SQL堪稱完美的解決了程序員新手的刪庫跑路的問題,高興吧,你學到了新姿勢,但是如果想面試給面試管留下好映像,上面的知識好像還不夠,有必要好好深入研究下MySql的權限了。
這里有個小的知識點需要先具備,在mysql中的權限不是單純的賦予給用戶的,而是賦予給”用戶+IP”的
比如dev用戶是否能登陸,用什么密碼登陸,並且能訪問什么數據庫等都需要加上IP,這樣才算一個完整的用戶標識,換句話說 'dev'@'192.168.0.168' 、'dev'@'127.0.0.1'與'dev'@'localhost' 這3個是完全不同的用戶標識(哪怕你本機的ip就是192.168.0.168)。
1.2.2. 用戶權限所涉及的表
有了用戶標識的概念接下來就可以看權限涉及的表了,這也是面試的時候加分項哦。
有幾張表你可以好好的記記的,mysql.user,mysql.db,mysql.table_priv,mysql_column_priv
你可以熟悉其中的user表,甚至手動的改過里面的數據(不合規范哦!)
那這些表有什么用,和權限又有什么關系呢?
l User的一行記錄代表一個用戶標識
l db的一行記錄代表對數據庫的權限
l table_priv的一行記錄代表對表的權限
l column_priv的一行記錄代表對某一列的權限
新建一個表account
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
`id` int(11) NOT NULL,
`name` varchar(50) DEFAULT NULL,
`balance` int(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_balance` (`balance`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `account` VALUES ('1', 'lilei', '900');
INSERT INTO `account` VALUES ('2', 'hanmei', '100');
INSERT INTO `account` VALUES ('3', 'lucy', '250');
INSERT INTO `account` VALUES ('5', 'tom', '0');
很詫異吧,mysql其實權限並不事特別low,權限的粒度甚至到了某一列上,舉例來說,有個表account表
對於前面創建的dev用戶我不想讓他訪問balance列,但是id和name列是可以訪問的,這樣的需求在工作中不是沒有。
grant select(id,name) on mall.account to 'dev'@'192.168.244.%';
這時候可以在分別看下table_priv,column_priv的數據
這個就應該豁然開朗了吧
REVOKE SELECT on mall.* from 'dev'@'192.168.244.%'
你使用dev登陸查詢試試
你再要查詢所有記錄?不好意思不讓查
而你查詢id,name查詢又是可以了。
1.2.3. Mysql的角色
1.2.3.1. 准備工作
MySql基於”用戶+IP”的這種授權模式其實還是挺好用的,但如果你使用Oracle、PostgreSQL、SqlServer你可能會發牢騷
這樣對於每個用戶都要賦權的方式是不是太麻煩了,如果我用戶多呢?有沒有角色或者用戶組這樣的功能呢?
好吧,你搓中了mysql的軟肋,很痛,在mysql5.7開始才正式支持這個功能,而且連mysql官方把它叫做“Role Like”(不是角色,長得比較像而已,額~~~)?
好咧,那在5.7中怎么玩這個不像角色的角色呢?
show variables like "%proxy%"
你得先把check_proxy_users,mysql_native_password_proxy_users這兩個變量設置成true才行
set GLOBAL check_proxy_users =1;
set GLOBAL mysql_native_password_proxy_users = 1;
當然,你也可以把這兩個配置設置到my.cnf中
1.2.3.2. 創建一個角色
create USER 'dev_role'
可能被你發現了,我這里創建得是個user,為了稍微像角色一點點,我給這user取名叫dev_role,而且為了方便也沒用使用密碼了。
1.2.3.3. 創建2個開發人員賬號:
create USER 'deer'
create USER 'enjoy'
這兩個用戶我也沒設置密碼
1.2.3.4. 把兩個用戶加到組里面
grant proxy on 'dev_role' to 'deer'
grant proxy on 'dev_role' to 'enjoy'
可以看下其中一個用戶的權限
這里有個小的地方需要注意:如果你是遠程鏈接,你可能會收獲一個大大的錯誤,你沒有權限做這一步,這個時候你需要再服務器上執行一條
GRANT PROXY ON ''@'' TO 'root'@'%' WITH GRANT OPTION;
1.2.3.5. 給角色dev_role應該有的權限
有了用戶了,這用戶也歸屬到了dev_role這角色下面,那接下來要做的就很簡單了,根據業務需求給這角色設置權限就好了
grant select(id,name) on mall.account to 'dev_role'
1.2.3.6. 測試
好咧,大功告成,現在使用'deer'用戶登陸系統試試
select id ,name from mall.account
你可能又會問,這種角色的權限是存哪的呢?
給你看表