循序渐进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)--- 图标的维护和使用
循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理的更多相关文章
- 循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合
循序渐进VUE+Element 前端应用开发的系列文章中,前面介绍了系统各个功能的处理实现,本篇随笔从一个主线上介绍前后端开发的整合,让我们从ABP框架后端的查询接口的处理,前端API接口调用的封装, ...
- 循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理
在前面随笔<循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理>介绍了一个系统最初接触到的前端登录处理的实现,但往往对整个系统来说,一般会有很多业务对 ...
- 循序渐进VUE+Element 前端应用开发(14)--- 根据ABP后端接口实现前端界面展示
在前面随笔<循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理>简单的介绍了一个结合ABP后端的登陆接口实现前端系统登陆的功能,本篇随笔继续深化这一主 ...
- 循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理
在前面随笔<循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理>中介绍了用户管理模块的内容,包括用户列表的展示,各种查看.编辑.新增对话框的界面处理和后台数据处 ...
- 循序渐进VUE+Element 前端应用开发(17)--- 菜单资源管理
在权限管理系统中,菜单也属于权限控制的一个资源,应该直接应用于角色,和权限功能点一样,属于角色控制的一环.不同角色用户,登录系统后,出现的系统菜单是不同的.在VUE+Element 前端中,我们菜单结 ...
- 循序渐进VUE+Element 前端应用开发(18)--- 功能点管理及权限控制
在一个业务管理系统中,如果我们需要实现权限控制功能,我们需要定义好对应的权限功能点,然后在界面中对界面元素的功能点进行绑定,这样就可以在后台动态分配权限进行动态控制了,一般来说,权限功能点是针对角色进 ...
- 循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码
VUE+Element 前端应用,比较不错的一点就是界面组件化,我们可以根据重用的指导方针,把界面内容拆分为各个不同的组合,每一个模块可以是一个组件,也可以是多个组件的综合体,而且这一个过程非常方便. ...
- 循序渐进VUE+Element 前端应用开发(26)--- 各种界面组件的使用(2)
在我们使用Vue+Element开发前端的时候,往往涉及到很多界面组件的使用,其中很多直接采用Element官方的案例即可,有些则是在这个基础上封装更好利用.更少代码的组件:另外有些则是直接采用第三方 ...
- 循序渐进VUE+Element 前端应用开发(27)--- 数据表的动态表单设计和数据存储
在我们一些系统里面,有时候会需要一些让用户自定义的数据信息,一般这些可以使用扩展JSON进行存储,不过每个业务表的显示项目可能不一样,因此需要根据不同的表单进行设计,然后进行对应的数据存储.本篇随笔结 ...
随机推荐
- 又抓了一个导致频繁GC的鬼--数组动态扩容
概述 本周有个同事过来咨询一个比较诡异的gc问题,大概现象是,系统一直在做cms gc,但是老生代一直不降下去,但是执行一次jmap -histo:live之后,也就是主动触发一次full gc之后, ...
- PIC单片机的for定时
看到公司的一个项目上的用的for定时 但是网上查找看到<PIC16系列单片机C程序设计与PROTEUS仿真> 上有关于for语句的定时 void Delay(unsigned int n) ...
- 《学习scrapy框架爬小说》的进一步完善
一.完善目标: 1.为方便使用,把小说拼音或英文名,小说输出中文名,第一章节url地址变量化,修改这些参数即可爬取不同的小说. 2.修改settings.py设置文件,配置为记录debug的log信息 ...
- DCL单例为什么要加Volatile
拿一个对象创建赋值来说 class T{ int elem = 1; } T t = new T(); 上段代码转换成汇编码为: 0 new #2 <T> 3 dup 4 invokesp ...
- 【Linux】yum库的配置
链接–>CentOS7之yum仓库配置
- Java实现 LeetCode 524 通过删除字母匹配到字典里最长单词(又是一道语文题)
524. 通过删除字母匹配到字典里最长单词 给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到.如果答案不止一个,返回长度最长且字典顺序最小的字符 ...
- Java实现 蓝桥杯VIP 算法训练 整数平均值
题目描述 编写函数,求包含n个元素的整数数组中元素的平均值.要求在函数内部使用指针操纵数组元素,其中n个整数从键盘输入,输出为其平均值. (样例说明:5为输入数据的个数,3 4 0 0 2 是以空格隔 ...
- Java实现选号码
选号码 Description CF打算换个手机号码,但是他去营业厅选号码的时候却把移动的客服小姐烦得不行,因为他太挑三捡四啦. 对于一个手机号的后六位数字(前面五位他就无所谓了)CF有很严格的要求, ...
- Java实现 蓝桥杯VIP 算法训练 删除多余括号
算法训练 删除多余括号 时间限制:1.0s 内存限制:512.0MB 问题描述 从键盘输入一个含有括号的四则运算表达式,要求去掉可能含有的多余的括号,结果要保持原表达式中变量和运算符的相对位置不变,且 ...
- Java实现 LeetCode 206 反转链表
206. 反转链表 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL ...