從零開始一起學Blazor WebAssembly 開發(4)


登錄模塊基本完成了,登錄主要用了以下幾個點:

1、后端采用的Abp Vnext 框架,這個框架自帶的IdentityServer4用戶角色權限控制,這個框架登錄研究了好一陣子,有幾個坑這里說下:

1)、Login.Razor利用HttpClient把用戶名和Rsa加密后的密碼提交到后端,后端把密碼解密后再往IdentityServer4的服務器獲取Token(用的oauth2.0 里的密碼模式),這塊知識網上能搜到不少,重點說一下這里有個坑,就是我之前不知道的,傳scope時,要傳 offline_access 這個 才能返回RefreshToken,因為IdentityServer4 默認提供的是JWT令牌,這個令牌相關的資料也能從網上搜到不少,這里就不講了。這個令牌有個缺點,就是服務器控制不了退出,解決辦法就是讓accesstoken有效時間變短,快到期時用refreshtoken 刷新,這個refreshtoken 我建議是保存在后端,不要往前端放,需要刷新時,前端傳請求過來。如果必須要放在前端,IdentityServer4 提供了OneTimeOnly這種設置。就是只能用一次就換的。

2)、IdentityServer4在每次請求之前框架有一個調用發現文檔的服務(httpClient.GetDiscoveryDocumentAsync)。這個服務就是返回IdentityServer4所支持的服務,研究了下Abp vnext框架自帶的,發現每次都調用這塊太耗時間。就想把結果放在緩存里,結果試了很久,發現Abp自帶的緩存框架處理不好這個,自己另外寫也不是不行。但是就感覺不太好。然后研究發現,其實IdentityServer4 也帶了一個發現文檔緩存的方法IDiscoveryCache,用這個就能實現了,具體使用方法這里講一下,因為我發現網上這個資料真不多:

(目前最新版的abp vnext已經實現了這個地方的緩存,不用自己寫了)

a 先注入

 //發現文檔緩存
            context.Services.AddSingleton<IDiscoveryCache>(r =>
            {
                var factory = r.GetRequiredService<IHttpClientFactory>();
                //var policy = new DiscoveryPolicy() { },用到可以加下
                var dc = new DiscoveryCache(configuration["IdentityClients:Default:Authority"], () => factory.CreateClient());
                //dc.CacheDuration = TimeSpan.FromMinutes(2); 緩存有效期,    默認是24小時,需要改的話自己改
                return dc;
            });

 

b 使用

 private readonly IDiscoveryCache _ddrcache;  
          //上下兩處代碼結合自己的項目的Service,自己分別寫。
           var disco = await _ddrcache.GetAsync();
            if (disco.IsError)
            {
                throw new Exception(disco.Error);
            }
            return disco;

 

3)、前端和后端不是在同一個域里邊,原本以為webAssembly 有點近似客戶端,應該不會有這個問題。發現還真的有,這就需要在后端設置下跨域設置,否則提交不了。

2、登錄后前端得到Token,要把Token信息保存到localstore里,這里用到了網上一個大神的解決方案,直接看代碼

 public class TokenUtil
    {
        private readonly IJSRuntime _jsRuntime;
        public TokenUtil(IJSRuntime jsRuntime)
        {
            _jsRuntime = jsRuntime;
        }
        public async Task SaveAccessToken(string accessToken)
        {
            await _jsRuntime.InvokeVoidAsync("wasmHelper.saveAccessToken", accessToken);
        }
        public async Task<String> GetAccessToken()
        {
            return await _jsRuntime.InvokeAsync<String>("wasmHelper.getAccessToken");
        }
        public async Task RefreshToken(string tokenValue)
        {
            var httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + tokenValue);
            await httpClient.GetFromJsonAsync<TokenInfo>("");
        }
    }

 

var wasmHelper = {};

wasmHelper.ACCESS_TOKEN_KEY = "__access_token__";

wasmHelper.saveAccessToken = function (tokenStr) {
    localStorage.setItem(wasmHelper.ACCESS_TOKEN_KEY, tokenStr);
};

wasmHelper.getAccessToken = function () {
    return localStorage.getItem(wasmHelper.ACCESS_TOKEN_KEY);
};

 

登錄模塊完成了,剩下就是些細節了。沒有什么技術難題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM