問題
ABP 啟用租戶功能時,所有資料都會依租戶來隔離。
而在登入系統時,使用者需要選擇所屬的租戶後,
再輸入 帳號 及 密碼 來登入,如下,
假如系統限制一個使用者只能所屬性一個租戶,
而且希望使用者不需要多去選擇它的租戶,
而是希望使用者登入後,依它所屬的租戶來自動切換。
這樣子的話,在 ABP 中要如何做呢?
解法
預設 ABP Account 的做法如下,
1.使用者選擇所屬的租戶
1.1.系統將該租戶資訊寫到 _tenant
Cookie 之中
資訊在 Basic Theme/Account.cshtml
2.使用者輸入 帳號 及 密碼 登入
2.1.用 使用者帳號 及 租戶 找看看是否有該使用者,沒有則傳出錯誤訊息
2.2.用 使用者帳號 及 密碼 驗證密碼是否正確
2.3.Log 使用者登入事件
2.4.導回到首頁
資訊在 ABP Account/Login.cshtml.cs
- 註: Theme 請依您使用的 Theme 來調整
- 註: 預設使用者為 admin,新增
T1
租戶使用者tenant1User1@gss.com.tw
及T2
租戶使用者tenant2User2@gss.com.tw
,並新增他們所屬的產品資料
要解決以上的問題,可以將問題展開成以下的處理步驟,
1.將 選擇租戶的區塊 隱藏 起來
1.1.將 Basic Theme/Account.cshtml 複製到 系統 Web 專案中的 Themes\Basic\Layouts
目錄之中
1.2.將 選擇租戶的區塊 的程式碼,如果 URL 不是登入((!Context.Request.Path.Equals("/Account/Login", StringComparison.OrdinalIgnoreCase) )
)才顯示 (@if (MultiTenancyOptions.Value.IsEnabled
那段程式碼),如下,
1 | @using Microsoft.Extensions.Localization |
1.2.將 Basic Theme/_ViewImports.cshtml 複製到 系統 Web 專案中的 Themes\Basic
目錄之中
2.客製 使用者登入頁 ,改變登入 Logic
2.1.在 Pages/Account 目錄下,新增 Login.cshtml Razor Page
2.2.修改 Login.cshtml.cs
改繼承自 Volo.Abp.Account.Web.Pages.Account.LoginModel
2.3.類別名稱從 LoginModel
改成 CustomLoginModel
2.4.調整查詢使用者的方式(FindUserAsync)
2.5.使用 CurrentTenant.Change
using 區塊中呼叫 Volo.Abp.Account.Web.Pages.Account.LoginModel
的 OnPostAsync
Method
1 | using Microsoft.AspNetCore.Authentication; |
2.6.將 Account/Login.cshtml 內容覆蓋到 Pages/Account/Login.cshtml
之中
2.7.將 @model
改成 @model 你的專案.Web.Pages.Account.CustomLoginModel
,如下,
1 | @page |
要 Override 的檔案如下所示,
測試
1.使用 tenant1User1@gss.com.tw
登入後,可以發現已自動切到所屬的 T1
租戶,並會將該 T1
租戶 Id 寫到 _tenant
Cookie
2.使用 tenant2User2@gss.com.tw
登入後,可以發現已自動切到所屬的 T2
租戶,並會將該 T2
租戶 Id 寫到 _tenant
Cookie
結論
從上面我們可以學習到以下幾點,
- 如何客製
ABP Module
- 透過
IDataFilter.Disable<IMultiTenant>()
來讓 using 區塊中的查詢不會依租戶來篩選資料 - 透過
CurrentTenant.Change(tenantId)
來切換到不同的租戶 - 要將 租戶資訊寫到 Cookie ,可以使用
AbpMultiTenancyCookieHelper.SetTenantCookie
參考資源
Hide Tenant Switch from an ABP Framework Login page
ABP ASP.NET Core (MVC / Razor Pages) User Interface Customization Guide
ABP Get tenant ID from user table.