其實兩週前就寫好了,就是拖着一直沒補個README文檔。喜歡的同窗幫我上個星星: biu。有bug請issue我。碼雲地址: 碼雲biu
Biu,boot和vue的連讀而想到的名字。一個基於Spring Boot和Vue的Web開發腳手架,整合和最基礎的RBAC權限控制,包括:菜單權限、按鈕權限、接口權限。
效果圖:javascript
請先安裝好依賴的開發環境:Java八、Gradle、Node.js、vue-cli。我本身使用的是Gradle4.6,Node8.11.1,vue-cli 2.9.3,建議使用Intellij IDEA。php
克隆項目到本地:css
git clone https://github.com/CaiBaoHong/biu
打開IDEA,File - Settings - Build Execution Deployment - Build Tools - Gradle
配置好本機Gradle的路徑。html
打開IDEA,File - Open
打開biu項目的路徑,導入項目,彈出Gradle導入引導窗口的,按下一步就行,肯定後項目開始初始化,
過程有點慢,其實就是下載server模塊中Gradle聲明的項目依賴。前端
下載好依賴後,咱們還須要下載browser模塊的依賴。在IDEA左下角打開一個Terminal命令行終端。cd browser
而後npm install
,等待依賴安裝完成。vue
而後再新建兩個Terminal命令行終端,即一共建三個命令行終端。java
在第1個終端輸入:nginx
cd server gradle build --continuous
啓動gradle的持續構建git
在第2個終端輸入:github
cd server gradle bootRun
啓動spring boot。有時候因爲持續構建沒有編譯好,會致使spring boot啓動失敗。多試幾回就行。
在第3個終端輸入:
cd browser npm run dev
啓動spring boot。有時候因爲持續構建沒有編譯好,會致使spring boot啓動失敗。多試幾回就行。
待三個終端都啓動完成,在瀏覽器頁面訪問前端頁面:http://localhost:9527
,頁面上的ajax請求會轉發到java後臺的8888
端口。
後端模塊server
因爲使用了Gradle的持續構建,當咱們編輯任何java代碼時候,就會觸發構建,spring boot會自動從新加載,無需咱們本身手動重啓。
前端模塊browser
是用vue-element-admin
這個腳手架來作的,改動代碼也無需重啓。更多詳情請看:vue-element-admin
打包server模塊:
cd server gradle build
而後上傳到服務器,啓動:
java -jar server.jar
打包browser模塊:
cd browser npm run build:prod
而後上傳到服務器,實用nginx
對外提供網頁內容,以及將網頁的ajax請求轉發到server.jar
的後臺。如下參考的配置:
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; # compress static html files gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_comp_level 9; gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; # virtual host for jujuju server{ listen 80; index index.html; root /data/production/jujuju/html; } # virtural host for aaa/web 【就在這裏!!】 server{ listen 9527; index index.html; root /data/production/aaa/dist; location /api/v1 { # proxy request to java server proxy_pass http://localhost:8888; } } include /etc/nginx/conf.d/*.conf; }
1.如何整合shiro
網上找到的文章,基本上都不是基於Spring Boot的starter來整合的,因此代碼量比較多,並且比較繁雜。
其實shiro官方提供了starter,可讓咱們優雅地把shiro整合到spring boot中。請看官網相關文檔:
Integrating Apache Shiro into Spring-Boot Applications
2.權限管理的細節
在「權限管理」菜單中。權限數據分爲菜單、按鈕、接口三種。
菜單權限元數據
菜單的權限元數據是定義在browser/src/router/index.js
中的,
在這裏定義的路由就能夠顯示成菜單。這些菜單路由能夠添加meta.perm
屬性來聲明訪問該菜單所須要的權限值,而這個權限值,就是權限的元數據。
因爲這個元數據是定義在前端的,後端的數據庫中sys_perm
表不必定有記錄。
因此菜單權限元數據中會有一個他「同步」按鈕,點擊便可把頁面上定義的權限值同步保存到後臺數據庫中。
按鈕權限元數據
按鈕權限是歸屬於菜單下的,這樣有助於咱們區分類似的按鈕。好比,用戶管理菜單下有「添加用戶」,角色管理菜單下有「添加角色」,兩個「添加」按鈕,若是不各自掛載在對應菜單下,比較容易混淆。
按鈕權限元數據是在數據庫中直接定義的,因此對按鈕權限元數據的增刪查改,都是操做數據庫中的數據。
接口權限元數據
接口的權限元數據是定義在server/com/abc/controller
目錄下的各類Controller中的,
在Controller的類上,會優先查找@PermInfo
的value屬性做爲接口模塊的權限名,查找@RequiresPermissions
的值做爲接口模塊的權限值。
若是沒有,則會把Controller類名做爲接口模塊權限的名稱,把@RequestMapping
做爲接口模塊權限的權限值。
對於在Controller的方法,只有註解了@RequiresPermission
的方法,纔會被視爲接口權限元數據展現在「權限管理」菜單中。
獲取接口權限元數據的邏輯是這樣的:優先查找@PermInfo
的value屬性做爲接口的權限名,查找@RequiresPermissions
的值做爲接口模塊的權限值。
若是沒有@PermInfo
,則會把Controller方法名做爲接口模塊權限的名稱
因爲接口權限元數據的獲取都會獲取備選值,因此您沒必要擔憂沒有使用@PermInfo
來聲明權限名稱或權限值而致使沒法顯示接口權限元數據。
3.爲何菜單權限和接口權限都不直接在數據庫中維護元數據
這樣作是爲了數據方便維護,當前端編輯完菜單路由數據或後端編輯完接口,還要「手工複製一份」到數據庫,是很累很笨的事情。因此這裏採用「同步」的方法把元數據寫入sys_perm
表。
4.接口權限是啥?等同於按鈕權限嗎?
接口權限是爲了保護後臺接口作的權限控制,它不等同與前臺頁面上的按鈕權限,按鈕權限是頁面上根據用戶登陸後返回的權限值,判斷用戶是否有按鈕上聲明的權限值,若是沒有就不顯示該按鈕。可是接口仍是能夠經過http來調用的,因此須要接口權限的控制。並且,有的場景下,前臺的一個按鈕,不必定對應後臺的一個接口調用,也有多是多個接口的調用。因此我這裏把「按鈕」和「接口」的概念區分開了。