1. 程式人生 > >循序漸進VUE+Element 前端應用開發(12)--- 整合ABP框架的前端登入處理

循序漸進VUE+Element 前端應用開發(12)--- 整合ABP框架的前端登入處理

VUE+Element 前端是一個純粹的前端處理,前面介紹了很多都是Vue+Element開發的基礎,從本章隨筆開始,就需要進入深水區了,需要結合ABP框架使用(如果不知道,請自行補習一下我的隨筆:ABP框架使用),ABP框架作為後端,是一個非常不錯的技術方向,但是前端再使用Asp.NET 進行開發的話,雖然會快捷一點,不過可能顯得有點累贅了,因此BS的前端選項採用Vue+Element來做管理(後續可能會視情況加入Vue+AntDesign),CS前端我已經完成了使用Winform+ABP的模式了。本篇隨筆主要介紹Vue+Element+ABP的整合方式,先從登入開始介紹。

 1、ABP開發框架的回顧

ABP是ASP.NET Boilerplate的簡稱,ABP是一個開源且文件友好的應用程式框架。ABP不僅僅是一個框架,它還提供了一個最徍實踐的基於領域驅動設計(DDD)的體系結構模型。

啟動Host的專案,我們可以看到Swagger的管理介面如下所示。

我們登入獲得使用者訪問令牌token後,測試字典型別或者字典資料的介面,才能返回響應的資料。

我根據ABP後端專案之間的關係,整理了一個架構的圖形。

應用服務層是整個ABP框架的靈魂所在,對內協同倉儲物件實現資料的處理,對外配合Web.Core、Web.Host專案提供Web API的服務,而Web.Core、Web.Host專案幾乎不需要進行修改,因此應用服務層就是一個非常關鍵的部分,需要考慮對使用者登入的驗證、介面許可權的認證、以及對審計日誌的記錄處理,以及異常的跟蹤和傳遞,基本上應用服務層就是一個大內總管的角色,重要性不言而喻。

對於通過Winform方式展示介面,以Web API方式和後端的ABP的Web API服務進行資料互動,是我們之前已經完成的專案,專案介面如下所示。

主體框架介面採用的是基於選單的動態生成,以及多文件的介面佈局,具有非常好的美觀性和易用性。

左側的功能樹列表和頂部的選單模組,可以根據角色擁有的許可權進行動態構建,不同的角色具有不同的選單功能點,如下是測試使用者登入後具有的介面。

 

2、Vue+Element整合ABP框架的前端登入處理

之前我們開發完成的Vue+Element的前端專案,預設已經具有登入系統的功能,不過登入是採用mock方式進行驗證並處理的,本篇隨筆介紹是基於實際的ABP專案進行使用者身份的登入處理,這個也是開發其他介面展示資料的開始步驟,必須通過真實的使用者身份登入後臺,獲得對應的token令牌,才能進行下一步介面的開發工作。

例如對應登入介面上,介面效果如下所示。

在使用者登入介面中,我們處理使用者登入邏輯程式碼如下所示。

    // 處理登入事件
    handleLogin() {
      this.$refs.loginForm.validate(valid => {
        if (valid) {
          this.loading = true
          this.$store
            .dispatch('user/login', this.loginForm)
            .then(() => {
              this.$router.push({ path: this.redirect || '/' })
              this.loading = false
            })
            .catch(() => {
              this.loading = false
            })
        } else {
          console.log('error submit!!')
          return false
        }
      })
    }

這裡主要就是呼叫Store模組裡面的使用者Action處理操作。

例如對於使用者store模組裡面的登入Action函式如下所示。

const actions = {
  // user login
  login({ commit }, userInfo) {
    const { username, password } = userInfo
    return new Promise((resolve, reject) => {
      login({ username: username.trim(), password: password }).then(response => {
        const { result } = response // 獲取返回物件的 result
        var token = result.accessToken
        var userId = result.userId

        // 記錄令牌和使用者Id
        commit('SET_TOKEN', token)
        commit('SET_USERID', userId)

        // 儲存cookie
        setToken(token)
        setUserId(userId)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

而其中 login({ username: username.trim(), password: password }) 操作,是通過API封裝處理的呼叫,使用前在Store模組中先引入API模組,如下所示。

import { login, logout, getInfo } from '@/api/user'

 而其中 API模組程式碼如下所示。

export function login(data) {
  return request({
    url: '/abp/TokenAuth/Authenticate',
    method: 'post',
    data: {
      UsernameOrEmailAddress: data.username,
      password: data.password
    }
  })
}

這裡我們用了一個/abp的字首,用來給WebProxy的處理,實現地址的轉義,從而可以實現跨站的處理,讓前端呼叫外部地址就和呼叫本地地址一樣,無縫對接。

我們來看看vue.config.js裡面對於這個代理的轉義操作程式碼。

 而 http://localhost:21021/api 地址指向的專案,是我們本地使用ABP開發的一個後端Web API專案,我們可以通過地址 http://localhost:21021/swagger/index.html 進行介面的檢視。

 我們開啟獲取授權令牌的Authenticate介面,檢視它的介面定義內容

 

通過標註的1,2,我們可以看到這個介面的輸入引數和輸出JSON資訊,從而為我們封裝Web API的呼叫提供很好的參考。

ABP框架統一返回的結果是result,這個result裡面才是返回對應的介面內容,如上面的輸出JSON資訊裡面的定義。

所以在登陸返回結果後,我們要返回它的result物件,然後在進行資料的處理。

const { result } = response // 獲取返回物件的 result

然後通過result來訪問其他屬性即可。

var token = result.accessToken // 使用者令牌
var userId = result.userId // 使用者id

使用者登入成功後,並獲取到對應的資料,我們就可以把必要的資料,如token和userid儲存在State和Cookie裡面了。

// 修改State物件,記錄令牌和使用者Id
commit('SET_TOKEN', token)
commit('SET_USERID', userId)

// 儲存cookie
setToken(token)
setUserId(userId)

有了這些資訊,我們就可以進一步獲取使用者的相關資訊,如使用者名稱稱、介紹,包含角色列表和許可權列表等內容了。

例如對應使用者資訊獲取介面的ABP後端地址是 http://localhost:21021//api/services/app/User/Get 

 那麼我們前端就需要在API模組裡面構建它的訪問地址(/abp/services/app/User/Get)和介面處理了。

export function getInfo(id) {
  return request({
    url: '/abp/services/app/User/Get',
    method: 'get',
    params: {
      id
    }
  })
}

如上所示,在Store模組裡引入API模組,如下所示。

import { login, logout, getInfo } from '@/api/user'

然後在Store模組中封裝一個Action用來處理使用者資訊的獲取的。

  // 獲取使用者資訊
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo(state.userid).then(response => {
        const { result } = response
        console.log(result) // 輸出測試

        if (!result) {
          reject('Verification failed, please Login again.')
        }

        const { roles, roleNames, name, fullName } = result

        // 角色非空提醒處理
        if (!roles || roles.length <= 0) {
          reject('getInfo: roles must be a non-null array!')
        }

        commit('SET_ROLES', { roles, roleNames })
        commit('SET_NAME', name)
        // commit('SET_AVATAR', avatar) //可以動態設定頭像
        commit('SET_INTRODUCTION', fullName)
        resolve(result)
      }).catch(error => {
        reject(error)
      })
    })
  },

Vue + Element前端專案的檢視、Store模組、API模組、Web API之間關係如下所示。

 

 登入後我們獲取使用者身份資訊,在控制檯中記錄返回物件資訊,可以供參考,如下所示

  

有了token資訊,我們就可以繼續其他介面的資料請求或者提交了,從而可以實現更多的管理功能了。

後續隨筆將基於ABP介面對接的基礎上進行更多介面功能的開發和整合。 

 

列出一下前面幾篇隨筆的連線,供參考:

循序漸進VUE+Element 前端應用開發(1)--- 開發環境的準備工作

循序漸進VUE+Element 前端應用開發(2)--- Vuex中的API、Store和View的使用

循序漸進VUE+Element 前端應用開發(3)--- 動態選單和路由的關聯處理

循序漸進VUE+Element 前端應用開發(4)--- 獲取後端資料及產品資訊頁面的處理

循序漸進VUE+Element 前端應用開發(5)--- 表格列表頁面的查詢,列表展示和欄位轉義處理

循序漸進VUE+Element 前端應用開發(6)--- 常規Element 介面元件的使用

循序漸進VUE+Element 前端應用開發(7)--- 介紹一些常規的JS處理函式

循序漸進VUE+Element 前端應用開發(8)--- 樹列表元件的使用

循序漸進VUE+Element 前端應用開發(9)--- 介面語言國際化的處理

循序漸進VUE+Element 前端應用開發(11)--- 圖示的維護和