<MySQL>もう、これで迷わない！ロール(role)と権限(authority)の関係について

#ロールと権限の関係

権限周りの開発に携わった時に、「あれ、どういうことだっけ？！？！？」
とこんがらがってしまい、若干パニクった記憶があるので、ロールと権限についてまとめようと思いやす。

ベン図で、シンプルに表すとこんな感じです。（だと認識してます。）
![スクリーンショット 2021-02-04 10.32.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075243/4bb32f1e-0a7f-1f1b-2de4-0735481924e0.png)

まあ、つまり、権限よりもロールの方が大きい概念で、
**ロールに権限を紐付ける**
というイメージです。

#1. ロール(Role)とは

日本語訳にすると、**役割**ですねえ。

つまり、**ユーザーに役割を演じさせること** とイメージするとわかりやすいかと思います。

人それぞれいろんな役割を持って生きていますねえ

例えば、自分なんかの平社員は、会社で入れないルームや、見れないファイルがあったり、
所属してる部署のファイルはみれるけど、他部署のフォルダを開ける権限がなかったりと、制限があったりします。
でも、上司は、入れるルームが多かったり、見れないファイルも見れたり、部署間にまたがったファイルだって見れちゃいます。

それって、格差だ、格差社会だ、、、なんて嘆きたくもなりますが、
結局は、**その人の役割に、許可されてできること**が与えられているということですね。

よく、システムのロールなんかでは、**管理者、編集者、閲覧者**みたいなレベルで分けられることがありますね


#2. 権限(Authority)とは

権限とは、ロールより小さな単位の「できること」の箇条書きみたいなものです。
権限を列挙して、それをロールに紐づけて、ロールの定義を決めていきます。

例えば、
会社でのワークフロー業務なんかイメージしてもらえるといいと思いますが、

- 購入申請ができる
- 申請の承認ができる
- 差戻しできる
- 購入ができる

みたいな権限があるとします。

普通の社員の人は、購入申請を出しますが、自分では、承認できません。
その社員の上司は、承認ができたり、差し戻しができたりしますが、実際に購入はしません。
総務担当の社員が購入ができます。

といったように、**権限というのは、シンプルに「できること、許可されていること」の一つ一つの行為**のこと。



#3. ロールと権限の関係を図で表すと
以下のテーブルのように、役職（ロール）と見立てて、権限を紐づけていくとこうなります。

| 役職 | 権限1 | 権限2 |権限3 |権限4 |
|:-:|:-:|:-:|:-:|:-:|
| 普通社員 | 購入申請ができる |   |||
| 普通上司 | 購入申請ができる | 申請承認ができる |差戻しができる||
| 総務担当者 | 購入申請ができる | 申請承認ができる |差戻しができる|購入ができる|


まあ、この図だけ見ると、
総務担当者、職権濫用最強説、なんでも買えちゃうウハウハ！みたいな感じなってしまいますが、
あくまで、極端な例ですが、シンプルな例としてご了承をw

ということで、

それぞれのロールに、できること・許可すること、を紐づけてます。

これがシンプルに、ロールと権限の関係になります。


#4. 実際にテーブルにしてみると
（※飽くまで一つのやり方にすぎませんので、参考程度に見ていただけると◎）

`user_roles`テーブルと`role_authorities`テーブルの二つを用意します。
`user_roles`テーブルは`roles_id`を用いて、`role_authorities`テーブルと**リレーションを張る**関係になります。
（リレーションを張るって要するに、紐づけるってことです、なんか**張る**んですよね、張る(?)、表現が気になりますw）
 

####user_rolesテーブル
- `role_id == 1`：普通社員の役割
- `role_id == 2`：普通上司の役割
- `role_id == 3`：総務担当者の役割

という感じで置おきたいと思います。

| id | user_id | role_id | created_by | create_at | updated_by | updated_at | delete_flg |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|  1 | user1 | 1 | admin |  2021-02-04 00:00:00 | null | 2021-02-04 00:00:00 | 0 |
|  2 | user2 | 2 | admin |  2021-02-04 00:00:00 | null | 2021-02-04 00:00:00 | 0 |
|  3 | user3 | 3 | admin | 2021-02-04 00:00:00  | null | 2021-02-04 00:00:00 | 0 |


####role_authoriesテーブル

- `auth1_flg`：購入申請ができる
- `ayth2_flg`：申請の承認ができる
- `auth3_flg`：差戻しできる
- `auth4_flg`：購入ができる

という感じでそれぞれの権限と紐付き、
authorityの権限を、`0:許可しない、1:許可する`
というフラグ形式で運用する方針でいきたいと思います。


| id | role_id | auth1_flg| auth2_flg|auth3_flg|auth4_flg | created_by | create_at | updated_by | updated_at | delete_flg |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|  1 | 1 | 1 | 0 | 0 | 0 | admin |  2021-02-04 00:00:00 | admin | 2021-02-04 00:00:00 | 0 | 0 | 0 |
|  2 | 2 | 1 | 1 | 1 | 0 | admin |  2021-02-04 00:00:00 | admin | 2021-02-04 00:00:00 | 0 | 0 | 0 |
|  3 | 3 | 1 | 1 | 1 | 1 | admin | 2021-02-04 00:00:00  | admin | 2021-02-04 00:00:00 | 0 | 0 | 0 |

するとどうでしょう!?

#5. ロールと権限の紐付きができました!!
以下のSQL文を流すことで、ロールズに紐づいた権限を引っ張ってくることができるようになります。
`user_roles`に`role_authorities`を左外部結合して、
`delete_flg`が`0`、つまり、論理削除的に消されていないデータを引っ張ってこれます。


```sql
SELECT * 
FROM user_roles LEFT JOIN role_authorities on user_roles.role_id = role_authorities.role_id
WHERE user_roles.delete_flg = 0 AND role_authorities.delete_flg = 0; 
```

####<解説>
`user1`の人は、**roleが1**、つまり普通社員だから、
権限としては、`auth1_flg`だけ`1`として立っている、つまり権限として許可されているので、
**購入申請ができて**、その他の権限は持っていないから、他はなにもできない人だね〜

っていうことが表現できるようになりました。

他に何もできない人だね〜　ってそこだけ切り取って、見てみると、かなり凌辱感が否めないですが、

そんなことはありません、普通社員、頑張ってます！^^


#6. まとめ

ということでまとめます。

- ロールと権限の関係は、`ロール>=権限`
- ロールは役割であって、**役割に権限を紐づける**関係
- 権限は、**できること・許可すること**の箇条書きみたいなもので、「〇〇ができる」みたいにシンプルなアクション
- ロールと権限を別テーブルでもって紐づけて使うと便利


以上です。

ありがとうございました！