Tạo user và phân quyền cho MySQL/MariaDB

Nghe có vẻ đây là một chủ đề đơn giản, nhưng nếu đây lần đầu bạn tìm hiểu vấn đề này thì cũng không dễ lắm đâu nhé. Hệ thống user và phân quyền của MySQL cũng không mấy phức tạp đâu, chỉ mất một chút thời gian làm quen thôi. Mình cùng bắt đầu

Nghe có vẻ đây là một chủ đề đơn giản, nhưng nếu đây lần đầu bạn tìm hiểu vấn đề này thì cũng không dễ lắm đâu nhé.
Hệ thống user và phân quyền của MySQL cũng không mấy phức tạp đâu, chỉ mất một chút thời gian làm quen thôi.
Mình cùng bắt đầu nào.

Tạo user

Để tạo user với MySQL chúng ta dùng query CREATE USER. Bạn có thể thêm IF NOT EXISTS để query không lỗi nếu user đã
tồn tại sẵn.

CREATEUSER[IFNOTEXISTS]'<username>'[IDENTIFIED BY'<password>'];

Ví dụ mình tạo user myussername thì query sẽ như thế này,

CREATEUSERIFNOTEXISTS'myusername';

Nếu bạn muốn set password nữa thì thêm IDENTIFIED BY như này.

CREATEUSERIFNOTEXISTS'myusername' IDENTIFIED BY'mypassword';

Giờ nếu nhỡ bạn quên chưa set password hoặc muốn đổi sang cái khác thì chúng ta sẽ dùng ALTER USER.

ALTERUSER'myusername'@'%' IDENTIFIED BY'mypassword';

Nếu bạn muốn login mà không cần password nữa thì có thể set lại password thành empty như thế này.

ALTERUSER'myusername'@'%' IDENTIFIED BY'';

Bạn có thế thấy lần này mình có thêm đoạn @'%' ở phía sau username nữa.
Với MySQL, mỗi user sẽ được xác định bởi 2 thứ: usernamehost mà bạn đang truy cập đến.
Nghĩa là password và quyền của myusername khi bạn kết nối với MySQL từ localhost hoặc từ một client/server
có thể sẽ khác nhau hoàn toàn.

Ví dụ mình tạo user như thế này.

CREATEUSERIFNOTEXISTS'myusername'@'localhost';CREATEUSERIFNOTEXISTS'myusername'@'%' IDENTIFIED BY'mypassword';

Thì mình sẽ login được vào myusername mà không cần password nếu dùng mysql client trên cùng một máy với nơi chạy
MySQL như thế này.

mysql -u myusername

Nhưng nếu login từ một máy khác thì sẽ bị từ chối ngay.

$ mysql -h 172.17.0.1 -P 3306 -umyusername

ERROR 1045 (28000): Access denied for user 'myusername'@'172.17.0.1' (using password: NO)

Mà phải dùng password như thế này thì mới login được

mysql -h 172.17.0.1 -P 3306 -umyusername -pmypassword

Nếu bạn không set host thì mặc định nó sẽ là % như mình set ở trên, có nghĩa là tất cả các host trừ những cái đã được
set riêng (như ở trên là trừ localhost). Nếu bạn không cần phân quyền riêng cho từng host thì cứ để mặc định là được
rồi.

Một chút lưu ý là localhost127.0.0.1 khác nhau nhé 🤪. localhost chỉ dùng cho khi kết nối với MySQL qua
Unix socket (/var/run/mysqld/mysqld.sock), là mặc định của mysql client. Các ứng dụng khác thì thường kết nối qua
TCP connection nên sẽ sử dụng host 127.0.0.1.

Để xem các user đã được tạo, bạn có thể query từ bảng mysql.user

SELECTuser, host, password FROM mysql.user;
+----------------+-----------+-------------------------------------------+
| User           | Host      | Password                                  |
+----------------+-----------+-------------------------------------------+
| mariadb.sys    | localhost |                                           |
| root           | localhost | *54904D5A3736765873CCE669C7215D541A001B67 |
| root           | %         | *54904D5A3736765873CCE669C7215D541A001B67 |
| myusername     | localhost |                                           |
| myusername     | %         | *7F6C7C0B40B56A2B136E8C2A23E1EDA4BD3ADFCD |
+----------------+-----------+-------------------------------------------+

Phân quyền cho user

Mình sẽ tạo một chiếc DB tên là mydatabase như thế này.

CREATEDATABASEIFNOTEXISTS'mydatabase';

Để trao quyền cho user thao tác trên DB, chúng ta sẽ dùng GRANT. Thông thường user sẽ có các quyền sau:

  • CREATE: tạo DB và table.
  • DROP: xóa DB và table.
  • SELECT: query dữ liệu trong bảng.
  • DELETE: xóa dữ liệu trong bảng.
  • INSERT: thêm dữ liệu vào bảng.
  • UPDATE: update dữ liệu trong bảng.
  • GRANT OPTION: cấp quyền cho các user khác.
  • EXECUTE: chạy stored procedure, function.
  • ALL PRIVILEGES: tất cả mọi quyền.

Query để trao quyền cho user sẽ như thế này;

GRANT<permission>ON<database_name>.<table_name>TO'<username>'@'<host>';

Chúng ta vẫn có user được xác định bởi usernamehost như đã nói từ phần trước.
Bạn có thể chọn trao quyền cho từng bảng nhất định trong DB hoặc tất cả các bảng bằng cách dùng *.
Ví dụ mình cấp quyền cho myusername được phép cấp quyền cho user khác như thế này:

GRANTGRANTOPTIONON mydatabase.*TO'myusername'@'%';

Để xóa quyền đã tro cho user bạn có thể dùng REVOKE với cú pháp tương tự:

REVOKE<permission>ON<database_name>.<table_name>TO'<username>'@'<host>';

Ví dụ:

REVOKEGRANTOPTIONON mydatabase.*TO'myusername'@'%';

Thường thì khi phân quyền cho user, user sẽ được chia thành 3 loại:

  • owner: có tất cả mọi quyền với DB.
  • readonly: chỉ có quyền đọc dữ liệu.
  • readwrite: có quyền đọc và ghi dữ liệu.

Áp dụng phần trên, chúng ta sẽ có query để set quyền owner cho user như thế này.

GRANTALLPRIVILEGESON mydatabase.*TO'myusername'@'%';

Giả sử mình muốn set quyền readonly cho user mydatabase_readonly thì query sẽ như thế này.

GRANTSELECTON mydatabase.*TO'mydatabase_readonly'@'%';

Cuối cùng là set quyền readwrite cho mydatabase_readwrite:

GRANTSELECT,INSERT,UPDATE,DELETE,CREATE,DROPON mydatabase.*TO'mydatabase_readwrite'@'%';

Để xem các quyền đã được cấp cho user, bạn có thể dùng SHOW GRANTS.

SHOW GRANTS FOR'myusername';
+----------------------------------------+
| Grants for [email protected]%                |
+----------------------------------------+
| GRANT USAGE ON *.* TO `myusername`@`%` |
+----------------------------------------+

Mặc định thì user sẽ có một quyền USAGE như trên. Trông có thể hơi confusing một tí vì nhìn nó giống như là quyền truy
cập tất cả mọi database ấy, cơ mà thật ra USAGE có nghĩa là không có quyền gì cả 🤣. Nghĩa là mặc định user sẽ không
có quyền truy cập bất kì database nào cả.

Hết rồi. Cũng không khó tí nào phải không 😉. Chúc bạn thành công nhé.

Nguồn: viblo.asia

Bài viết liên quan

Thay đổi Package Name của Android Studio dể dàng với plugin APR

Nếu bạn đang gặp khó khăn hoặc bế tắc trong việc thay đổi package name trong And

Lỗi không Update Meta_Value Khi thay thế hình ảnh cũ bằng hình ảnh mới trong WordPress

Mã dưới đây hoạt động tốt có 1 lỗi không update được postmeta ” meta_key=

Bài 1 – React Native DevOps các khái niệm và các cài đặt căn bản

Hướng dẫn setup jenkins agent để bắt đầu build mobile bằng jenkins cho devloper an t

Chuyển đổi từ monolith sang microservices qua ví dụ

1. Why microservices? Microservices là kiến trúc hệ thống phần mềm hướng dịch vụ,