從壹開始 [ Ids4實戰 ] 之四 ║ 使用者資料管理 & 前後端授權聯調

老張的哲學發表於2019-05-27

前言

 哈嘍~~~ 大家週一好!夏天到了,大家舒服了沒有,熟話說,打敗你的不是天真,是天真熱!?

 

過去的一週裡,發生了兩件事跟大家分享下:

①、有兩個小夥伴給我提供了 Working Online 的工作,簡單說了說,感覺應該不太適合,至少我不適合,前期雙方試探的成分太多了,我是不喜歡,同時也建議正在找OnLine工作的小夥伴需多多考慮可行性。

②、我決定開始《微講堂》了,具體可以參考右側公告欄,因為有些基礎比較薄弱的小夥伴,單單提供思路還是無法入門,所以提供線上手把手教學吧,這個我是完全無所謂,看你心情吧。

 

這幾天通過晚上對 IdentityServer4 的學習和研究,發現這個就是一個“大坑”(不是說功能不好,是裡邊有很多很多的內容需要學習),之前看官網, 關於 IdentityServer4 的教程,洋洋灑灑就過去了,感覺還挺簡單,發現要真是落地到專案裡了,自我感覺又有了壓迫感,文末結語中,我簡單的說了幾點問題,大家可以慢慢往下走,不過知識嘛,無外乎就是自己開心學習 和 自己學習掙錢,這兩個心理,加油吧。

當然平時工作之餘,還是要照顧下前後端分離專案的一些東西的,基礎不能丟,主要是三塊地方做了修改,這裡簡單的列一下,就不單獨的寫文章了,希望一直在看第一個專案的小夥伴,有緣可以看到吧,不過,就算是看不到也沒事兒,遇到了自然就知道了:

1、Blog.Vue 首頁的閃屏處理;// 知名博主@張飛洪提出的問題,不知道我是否修改對了;http://core-dotnet.com:8077

2、Blog.Admin 後臺框架調整優化;// ①登入頁樣式改版,②Tabs 導航條優化,③相容手機螢幕等;http://core-dotnet.com:2364

3、Blog.Core 後端專案增加 Wiki 頁;// 為了讓剛接觸框架的小夥伴能快速一覽,特地在 Github 上,建立了 Wiki ,只不過現在才打了個目錄,內容慢慢填,如果還有其他的不足之處,歡迎提建議;https://github.com/anjoy8/Blog.Core/wiki

 

突然轉話題,上次我們們第一次對專案進行持久化操作《三║ 詳解授權持久化 & 使用者資料遷移》,不知道小夥伴都看了多少,這裡再把幾個重要問題提一下,希望不要忘記了才好:

1、Ids4 一共用到了幾個上下文,分別的用處是什麼?

2、在遷移中,資料庫生成了多少表,各個模組又是幹什麼的?

3、Ids4 的良好擴充套件性,體現在哪裡?豐富性又體現在哪裡?

4、ApplicationUser 類是起到什麼作用的?

 

如果腦子裡有些東西,那就恭喜了,如果第一次看,或者完全不知道我在說什麼的話,請看上一集,今天會說說我在研究的過程中,遇到的兩個 Flag ?,也就是兩個問題,希望有心的小夥伴,可以幫忙思考下,歡迎找我討論,廢話不多說,開車,馬上講解今天的內容!??

 

 

零、今天要實現綠色的部分

 

 (知識結構圖,注意這是我自己的講解結構,和Ids4知識圖解無關)

 

 

 

一、使用者資料處理 —— Identity

我們們在上篇文章中,簡單的將 IdentityServer4 的結構進行持久化處理,並把前後端專案中的使用者資料進行遷移處理,最後修改了登入頁的樣式,基本滿足了登入和登出的操作,作為一個授權服務中心,僅僅只有登入是完全解決不了什麼問題的,至少應該對使用者資料進行常規操作處理,比如 CURD 等基礎操作。

正好,我們使用了 NetCore 自帶的 Identity 機制,可以幫助我們做一部分工作,因為它自己也封裝了一些方法,我們可以根據他們的方法,實當的做些擴充套件,從而達到相應的目的,具體有哪些操作,請往下看:

 

1、使用者資料展示(有許可權)

 既然有資料處理,肯定得有展示出來,當然,這個不是一定的,只是做下處理,如果你擔心會有資料安全問題的話,要麼不顯示資料,要麼只顯示無關痛癢的兩列,甚至可以直接加上許可權,只有超級管理員或者技術人員可以看到就行。我這裡僅僅是加了個登入許可權,只有登入的使用者才能看的到:

 

// 注入使用者管理
private readonly UserManager<ApplicationUser> _userManager;


 [HttpGet]
 [Route("account/users")]
 [Authorize]//可以自定義規則
 public IActionResult Users(string returnUrl = null)
 {
     ViewData["ReturnUrl"] = returnUrl;
     var users = _userManager.Users.Where(d => !d.tdIsDelete).OrderBy(d => d.UserName).ToList();//Identity 已經對內部的一些方法做了封裝,直接使用即可,如果你對 Net 自帶的 Identity 使用過的話,應該很容易上手。

     return View(users);
 }

 

注意下上邊的紅色標註的地方,下文會說到為啥這裡用到了 isDelete 。

我們簡單的對 User 頁面做了授權處理,必須登入狀態下才能有權訪問,如果是沒有登入,會直接跳轉到登入頁面:

 (帶許可權的使用者展示頁)

 

2、註冊

 關於註冊其實我們之前已經說過了,為什麼呢,因為我們在之前匯入使用者資料的時候,就已經用到了這個方法,只不過這裡單拎出來了,但是這裡有一個問題需要我們好好的思考思考,那就是角色的獲取!這裡就是我下邊要說的第一個“Flag”?,為什麼重要呢,不知道現在讀的你是否使用過 IdentityServer4 ,我也這幾天在考慮這個問題,授權中心肯定需要有使用者管理的,那很自然的,就會出現 “ 區分控制 ” 的問題,這裡簡單說下會出現的兩個情況:

1、前臺展示專案:如果我們的vue 專案,是一個前臺網站,比如 電商類 的或者 Blog.Vue 這樣的,很簡單,我們只需要在 api 上加上 [Authorize] 這個無具體規則的授權特性就行,大家先不要往下看,先停一分鐘想一想是不是這個情況。商城嘛,只需要使用者登入一下就可以購買了,我們不需要特地的區分商城使用者有什麼區別,有什麼三六九等,大家都是一樣,登入了,就可以任何操作,無論是買東西,還是寫文章,亦或者投票等等;

2、後臺管理專案:但是!還有另一種情況,那就是後臺管理,一個對使用者身份要求特別嚴格的一個系統,我們肯定不能僅僅在 api 介面地址上,加上 [Authorize] 這個簡單的特性就完事兒了,就比如我們的 Blog.Admin 專案,肯定需要一套複雜的授權策略機制,那就不得不用到使用者的角色資訊,或者其他的模組資訊,這就是我上邊說的 “區分控制”;(至於是基於角色的策略,還是模組化,我還在考慮中,目前先嚐試角色管理

3、猜想:你是不是想說使用基於角色+策略授權的 Hybrid Flow 混合模式?彆著急,以後的問題會說到,這裡提出這個問題,就是向給大家一個思路的過程。

 

如果是第二種情況的話,我們在使用者註冊的時候,就需要帶上 “角色” 這個資訊,比如我這裡先預設是一個 test 系統測試管理員的角色這個暫時這麼處理,後期我會再深入研究下,是不是這個模式,或者如果正再看的你很懂的話,歡迎指導下,不勝感激!)當然,如果你的專案不需要對使用者的許可權進行劃分,就比如我上邊的第一種情況,電商類,部落格類,只要不是後臺管理這種的前臺系統,都很簡單,只需要在 api 上加上 [Authorize] ,然後授權中心是不需要角色這個概念的。

我們學術討論嘛,當然是從複雜的著手,就把角色給考慮進去了,現在先寫死一個角色,我們以後的文章中會進一步討論這個複雜的情況:

 [HttpPost]
 [Route("account/register")]
 [ValidateAntiForgeryToken]
 public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null, string rName = "AdminTest")
        {
            ViewData["ReturnUrl"] = returnUrl;
            IdentityResult result = new IdentityResult();
            // 模型校驗
            if (ModelState.IsValid)
            {
                // 判斷使用者名稱是否存在,說明:如果是DDD設計思想,這中查重應該是寫在領域模型的。
                var userItem = _userManager.FindByNameAsync(model.LoginName).Result;
                if (userItem == null)
                {
                    // 轉成我們的實體模型,說明:這種多個實體轉換,可以使用 Dto
                    var user = new ApplicationUser
                    {
                        Email = model.Email,
                        UserName = model.LoginName,
                        LoginName = model.RealName,
                        sex = model.Sex,
                        age = model.Birth.Year - DateTime.Now.Year,
                        birth = model.Birth,
                        addr = "",
                        tdIsDelete = false
                    };
                    // 建立使用者,注意密碼的規範,比如必須有大小寫字母+數字+符號
                    result = await _userManager.CreateAsync(user, model.Password);
                    if (result.Succeeded)
                    {
                        // 使用者新增成功後,就需要新增宣告瞭,看自己需要多少吧,可以自定義擴充套件
                        result = await _userManager.AddClaimsAsync(user, new Claim[]{
                            // 這個 Name ,就是 Jwt 的唯一名字,也是頁面裡展示的名稱,比如是“測試賬號”,而不是登入名的“test1”
                            new Claim(JwtClaimTypes.Name, model.RealName),
                            new Claim(JwtClaimTypes.Email, model.Email),
                            // 是否需要進行 Email 郵件驗證
                            new Claim(JwtClaimTypes.EmailVerified, "false", ClaimValueTypes.Boolean),
                            // 這裡就是角色宣告
                            new Claim(JwtClaimTypes.Role, rName)
                        });
                        if (result.Succeeded)
                        {
                            // 新增成功,可以直接登入,這個就比如是我們的部落格專案或者電商專案,我們在授權中心註冊成功後,直接登入了,跳轉到前臺了。
                            //await _signInManager.SignInAsync(user, isPersistent: false);
                            return RedirectToLocal(returnUrl);
                        }
                    }
                }
                else
                {
                    ModelState.AddModelError(string.Empty, $"{userItem?.UserName} already exists");
                }
                // 收集全部異常資料,返回前臺
                AddErrors(result);
            }
            return View(model);
        }

 

上邊的就是註冊的主要程式碼,大家可以自己任意的擴充套件,然後重要的部分,我已經標紅,也寫上了詳細的註釋,特別簡單,都能看懂。

 

這一 Part 都很平常,最重要的一個問題還是那個角色這一塊,希望讀到這裡的都能看懂,想一想到底你的專案裡需不需要這樣的 Claim,不懂的歡迎來討論。

 

3、更新 與 邏輯刪除(有許可權)

上邊我們們說到了展示和新增,那下邊就是說到更新了(這個操作我帶上了最高的許可權,必須是超級管理員才能操作 [Authorize(Roles = "SuperAdmin")] ),你會問,為啥要把刪除和更新放到一起呢?其實我個人感覺邏輯是一樣的,平時開發肯定也都知道,邏輯刪除其實就是把“是否刪除” 這個欄位設定成 True 就行了,但是真的是這樣麼,我們慢慢往下看。

 首先更新使用者這個很簡單的,我就不多說什麼了,具體的可以看看程式碼,主要的邏輯就是平時的三步走:

1、查詢出當前人Model;

2、用檢視模型修改Model;

3、執行更新操作  _userManager.UpdateAsync(userItem); // 這裡要說下就是,Identity 自帶了很多擴充套件方法,大家需要自己好好的研究下,從而達到自己的相應目的。

 

更新說完了,下邊說說刪除,刪除其實本身就有兩種情況:

1、邏輯刪除,很自然,就是將資料更新下狀態,比如我們可以用上邊的方法,把當前操作人的 IsDeleted=True 即可,很簡單;

2、物理刪除,這個還是需要好好研究研究,我在官方的程式碼裡,沒有找到如何物理刪除的方法,可能還是需要開發者自己定義擴充套件吧;

 

 這就是我說的第二個 “Flag”? ,需要好好的思考思考,如果你已經忘了第一個 Flag 的話,請向上看,使用者註冊章節裡的角色問題。

 

 

(更新 & 刪除 有許可權 動圖)

 

 

4、重置密碼

 這個是目前為止稍微複雜一點的,需用用到流程,首先看動圖吧:

 

(重置/更新密碼 動圖)

 

這個過程其實很簡單,也是專案中必須使用到的功能,我相信任何一個網站,必須要用到這個重置和找回密碼的功能吧,當然生產環境很複雜,可能需要郵箱或者手機等來處理動態連結,我這裡只是提供一個思路,總結來說,流程說明如下:

1、輸入當時註冊郵箱;

2、獲取包含動態 Code 的安全連結(可通過發郵件的形式);

3、根據安全連結,設定新密碼;

4、重新登入;

 

核心程式碼(節選):

 

// 1、判斷郵箱
var user = await _userManager.FindByEmailAsync(model.Email);

// 2、生成重置密碼回撥連結
var code = await _userManager.GeneratePasswordResetTokenAsync(user);
var callbackUrl = Url.ResetPasswordCallbackLink(user.Id, code, Request.Scheme);
var ResetPassword = $"Please reset your password by clicking here: <a href='{callbackUrl}'>link</a>";

// 3、重置密碼
var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);

 

 

5、其他情況處理?

通過上邊的簡單說明,AccountController 這個控制器的內容, 我們們說完了,是不是就沒有問題了呢,不是!我們要研究,就要研究透徹,大家肯定注意到了這個專案中,基本都說到了,但是在核心的快速啟動資料夾 Quickstart 中,還有幾個控制器沒有說到:

 

 不光如此,在平時的開發中,我們還會遇到下邊這幾個業務邏輯操作:

1、如何找回註冊郵箱?

2、如何通過傳送郵件,從而達到郵件確認的目的?

3、如何實現FaceBook、Google登入?

4、如何更新使用者的角色等Claims?

5、如何重新整理 Token ?

 

上邊紅框中的那幾個控制器都是什麼意思?

下邊四條業務邏輯又該如何實現?

當前專案是不是還有其他不為我們知道的祕密?以後的章節再慢慢展開,請關注。

 

不過我們既然已經完成使用者的基本操作,我們就先停下上邊的疑惑問題,往下走走,看看 IdentityServer4 到底是如何通過 OpenID Connect 來操作的。

 

二、簡單授權模式 —— Implicit Flow OpenID

0、OpenID Connect授權模式

OPID 認證流程主要是由 OAuth2 的五種授權流程延伸而來的,它有以下 3 種:

  • Authorization Code Flow(授權碼模式):基於OAuth2的授權碼來換取Id Token和Access Token。
  • Implicit Flow(簡化模式):基於OAuth2的Implicit流程獲取Id Token和Access Token。
  • Hybrid Flow:混合Authorization Code Flow+Implici Flow獲取Id Token和Access Token。

注:OpenID Connect 為什麼沒有基於OAuth2的Resource Owner Password Credentials Grant和Client Credentials Grant擴充套件,Resource Owner Password Credentials Grant是需要應用提供賬號密碼的,賬號密碼都有了在獲取Id Token意義不大。Client Credentials Grant沒有使用者的參與所以獲取Id Token 也沒意義。這也能反映授權和認證的差異,以及只使用OAuth2來做身份認證的事情是遠遠不夠的,也是不合適的。

 

1、概念

簡化模式用於獲取訪問令牌(但它不支援令牌的重新整理,之所以所以稱為簡化模式,和授權碼模式比少了獲取授權碼的步驟),並對執行特定重定向URI的公共客戶端進行優化,而這一些列操作通常會使用指令碼語言在瀏覽器中完成,令牌對訪問者是可見的,且客戶端也不需要驗證。

 

簡化模式,主要有下邊三個特點:

1、用於“公共”客戶端;

2、客戶端應用直接從瀏覽器訪問資源;

3、沒有顯式的客戶端身份認證;

 

2、結構圖

 

為了配合大家理解,我這裡有兩個場景,大家腦子裡先有個畫面,然後往下看四個角色和流程圖:

場景一:部落格園登入,需要獲取騰訊的某一個QQ使用者的頭像和暱稱等資源;

場景二:前後端分離,Vue 專案需要獲取 Core 專案的 當前test1賬號的 資料;

 

首先先理解下四個角色:

1、Resource Owner(資源擁有者) —— 資源所有者,就比如我們授權登入中的,QQ使用者,他才是資源的擁有者。3143422472 / test1賬號

2、Resource Server(資源伺服器) —— 資源伺服器,用來儲存使用者資源(頭像,暱稱等)的伺服器,比如騰訊QQ。騰訊QQ伺服器 / Blog.Core 

3、Client(客戶端) —— 第三方客戶端,比如部落格園;https://www.cnblogs.com / Blog.Vue

4、Authorization Server(授權伺服器)—— 授權伺服器,用來作為認證第三方平臺的服務,比如騰訊的QQ互聯平臺。https://graph.qq.com/oauth2.0/show?whic...... / Blog.Idp

 

然後我們們看看具體的流程是怎樣的:

 

(流程1:參考網上畫的,可能不是很明瞭)

 

 (流程2:自己根據官網圖片做了下修改)

 

Tips:Web-Hosted Client Resource 伺服器相當於是一個儲存 accessToken 的地方,通常指瀏覽器中的儲存(cookie、localStorage、SessionStorge、js變數等),一般這個頁面是看不到的,而且一般情況是和 Client 客戶端寫在一起的,當然也有分開的。

 

步驟解析:

  1. 客戶端攜帶客戶端標識以及重定向URI到授權伺服器;
  2. 使用者確認是否要授權給客戶端;
  3. 授權伺服器得到許可後,跳轉到指定的重定向地址,並將令牌也包含在了裡面;
  4. 客戶端不攜帶上次獲取到的包含令牌的片段,去請求資源伺服器;
  5. 資源伺服器會向瀏覽器返回一個指令碼;
  6. 瀏覽器會根據上一步返回的指令碼,去提取在C步驟中獲取到的令牌;
  7. 瀏覽器將令牌推送給客戶端。

(A步驟)中需要用到的引數,注意在這裡要使用"application/x-www-form-urlencoded"格式:

  • response_type 必選項,此值必須為"token" 
  • client_id 必選項
  • redirect_uri 可選項
  • scope 可選項
  • state 建議選項

    例如:

GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
 

    (C步驟)中返回的引數包含:

  • access_token 必選項
  • token_type 必選項
  • expires_in 建議選項
  • scope 可選項
  • state 必選項

    例如:

HTTP/1.1 302 Found
     Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=example&expires_in=3600

 

上邊我們簡單的說了說 Implicit Flow 模式的相關知識點,不知道大家有沒有一點點感覺,如果不是很懂,正好感覺配合著下邊的程式碼研究下,二者結合會更好。

  

三、前後端專案授權聯調

 

 因為我們用到了前後端分離專案,所以一定是要三方處理,如果你現在使用的是 MVC 模式的話,我們以後的章節也會說到 授權碼授權模式(Authorization Code Flow),這裡先把簡化模式調通了:

1、授權服務端 —— Implicit(Blog.Idp)

 這個配置很簡單,在 Blog.Idp 專案中,大家別看是在 Config.cs 檔案裡,其實它已經在我們上一篇文章中,生成到了資料庫中,不懂的請回看上一篇文章

 new Client {
     ClientId = "blogvuejs",//客戶端id
     ClientName = "Blog.Vue JavaScript Client",
     AllowedGrantTypes = GrantTypes.Implicit,
     AllowAccessTokensViaBrowser = true,

     RedirectUris =           { "http://localhost:6688/callback" },//回撥頁面
     PostLogoutRedirectUris = { "http://localhost:6688" },
     AllowedCorsOrigins =     { "http://localhost:6688" },
     // 允許的前端獲取的作用域
     AllowedScopes = {
         IdentityServerConstants.StandardScopes.OpenId,
         IdentityServerConstants.StandardScopes.Profile,
         "roles",
         "blog.core.api"
     }
 }

 

 

 

 

 

2、資源服務端 —— Bearer(Blog.Core)

 

這裡的配置是在 Blog.Core 我們的資源伺服器中,在啟動檔案 Startup.cs 中,大家自行檢視,注意如果使用這個的話,請把 Jwt 認證給註釋掉:

services.AddAuthentication("Bearer")
  .AddIdentityServerAuthentication(options =>
  {
      options.Authority = "http://localhost:5002";//授權伺服器地址
      options.RequireHttpsMetadata = false;//是否Https
      options.ApiName = "blog.core.api";//我們在 Blog.Idp 中配置的資源伺服器名
  });

 

 

新增過程中,可能會需要引用擴充套件包 : IdentityServer4.AccessTokenValidation 這都是小問題,大家自行檢查即可。 

 

3、請求客戶端 —— Oidc(Blog.Vue)

上邊我們已經在兩個服務端做好了配置,客戶端如何處理,這個地方才是今天的重頭戲,無論是什麼客戶端,JS 或者 Vue、React、Ng 等等前端框架,都需要用到 oidc-client 這個外掛庫:

 

1、安裝

執行命令:npm install oidc-client --save

 

2、封裝

注意這個是一個js庫,我們就像之前將 SignalR 那樣,直接使用就行,不用在 main.js 中引用,但是還是需要先例項化一個使用者管理類 ApplicationUserManager  並配置建構函式,請注意這些引數都要和 Blog.Idp 授權伺服器配置一致。

在 src 資料夾下 新建 Auth 資料夾,並新增 applicationusermanager.js 來封裝我們的連線管理:

import { UserManager } from 'oidc-client'

class ApplicationUserManager extends UserManager {
  constructor () {
    super({
      authority: 'http://localhost:5002',// 授權服務中心地址
      client_id: 'blogvuejs',// 客戶端 id
      redirect_uri: 'http://localhost:6688/callback',// 登入回撥地址
      response_type: 'id_token token',
      scope: 'openid profile roles blog.core.api',// 作用域也要一一匹配
      post_logout_redirect_uri: 'http://localhost:6688' //登出後回撥地址
    })
  }

  async login () {
    await this.signinRedirect()
    return this.getUser()
  }

  async logout () {
    return this.signoutRedirect()
  }
}

 

同時為了配合其他頁面使用,我們封裝幾個常用的方法,在 Auth 資料夾下,新建 UserAuth.js 來封裝使用者的一些基本資訊:

import applicationUserManager from "./applicationusermanager";
const userAuth = {
  data() {
    return {
      user: {
        name: "",
        isAuthenticated: false
      }
    };
  },
  methods: {
    async refreshUserInfo() {//獲取使用者資訊
      const user = await applicationUserManager.getUser();
      if (user) {
        this.user.name = user.profile.name;
        this.user.isAuthenticated = true;
      } else {
        this.user.name = "";
        this.user.isAuthenticated = false;
      }
    }
  },
  async created() {
    await this.refreshUserInfo();
  }
};
export default userAuth;

 

 

3、發起 登入/登出 請求

我們封裝好了方法,下邊就是直接設計業務邏輯了,過程很簡單,在 App.vue 元件中:

 

1、每次路由跳轉需非同步獲取使用者資料;

2、發起非同步登入請求;

3、發起非同步登出請求;

 

import applicationUserManager from "./Auth/applicationusermanager";
import userAuth from "./Auth/UserAuth";

export default {
  name: "app",
  mixins: [userAuth],
  data: function() {
    return {};
  },
  watch: {
    $route: async function(to, from) {
      //這裡使用Id4授權認證,用Jwt,請刪之;
      // await this.refreshUserInfo();
    }
  },
  methods: {
    async login() {
      try {
        await applicationUserManager.login();
      } catch (error) {
        console.log(error);
        this.$root.$emit("show-snackbar", { message: error });
      }
    },
    async logout() {
      try {
        await applicationUserManager.logout();
        this.$store.commit("saveToken", "");
      } catch (error) {
        console.log(error);
        this.$root.$emit("show-snackbar", { message: error });
      }
    }
  }
};

 

 

4、回撥

在上邊的使用者管理配置中,我們用到了一個回撥頁面,這個很重要,因為我們在登入成功後,需要調整到客戶端,並且需要將資訊給儲存下來,就是上邊流程圖中,我們說到的 客戶端資源

 

 具體怎麼寫的,很簡單,在 views 檢視頁面資料夾下,新建一個 LoginCallbackView.vue 頁面:

import applicationUserManager from '../Auth/applicationusermanager'

export default {
  async created () {
    try {
      // 核心的就是這裡了
      await applicationUserManager.signinRedirectCallback()
        let user = await applicationUserManager.getUser()
        // 將 token 儲存在客戶端
        this.$store.commit("saveToken", user.access_token);
        // 調整首頁
        this.$router.push({name: 'home'})
    } catch (e) {
      console.log(e)
      this.$root.$emit('show-snackbar', { message: e })
    }
  }
}

 

 

 

四、結語

 

本文還是延續上篇文章的快速講解的風格,簡單連貫的把使用者管理和前後端聯調的內容通了一遍,總結一下:


1、分析了使用者是否需要角色等策略的緣由;

2、實現了對使用者的基本操作——CURD+重置密碼;

3、授權專案中還遺留了一片未知的知識塊,亟待探索;

4、實現了客戶端、資源伺服器、授權伺服器的第一次聯調;

5、重點講解了五大模式中的 Implicit Flow 簡化模式的概念和應用場景;

6、同時也把 Hybrid Flow 混合模式給引申出來,因為它基於 角色+策略 的授權;

 

當然,通過這一篇的學習,又開拓出了更多的未知領域,IdentityServer4 沒有我們想想的那麼難,但是肯定也不是一個 Demo 就能說的完的簡單,

如何解決文章中提到的,打算提到的,未提到的各種問題呢,請持續關注吧。

 

 

五、Github && Gitee

 https://github.com/anjoy8/Blog.IdentityServer

 

相關文章