Core + Vue 后台管理基础框架2——认证
1、前言
这块儿当时在IdentityServer4和JWT之间犹豫了一下,后来考虑到现状,出于3个原因,暂时放弃了IdentityServer4选择了JWT:
(1)目前这个前端框架更适配JWT;
(2)前后端分离的项目,如果上IdentityServer4,还要折腾点儿工作,比如前端配置、多余的回调等;
(3)跨度太大,团队、系统、历史数据接入都是问题,解决是可以解决,但时间有限,留待后续吧;
当然,只是暂时放弃,理想中的最佳实践还是IdentityServer4做统一鉴权的。
2、JWT认证实现
(1)Common项目下定义JWTConfig配置对象
(2)系统配置文件中增加JWT参数配置
此处配置与(1)中的配置对象是对应的。
(3)JWT处理程序及相关服务注册
services.Configure<JWTConfig>(Configuration.GetSection("JWT"));
var jwtConfig = Configuration.GetSection("JWT").Get<JWTConfig>();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = jwtConfig.Issuer,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.SymmetricSecurityKey)),
ValidateAudience = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromMinutes()
};
options.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
23 {
24 var userContext = context.HttpContext.RequestServices.GetService<UserContext>();
25 var claims = context.Principal.Claims;
26 userContext.ID = long.Parse(claims.First(x => x.Type == JwtRegisteredClaimNames.Sub).Value);
27 userContext.Account = claims.First(x => x.Type == ClaimTypes.NameIdentifier).Value;
28 userContext.Name = claims.First(x => x.Type == ClaimTypes.Name).Value;
29 userContext.Email = claims.First(x => x.Type == JwtRegisteredClaimNames.Email).Value;
30 userContext.RoleId = claims.First(x => x.Type == ClaimTypes.Role).Value;
31
32 return Task.CompletedTask;
33 }
};
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
上述代码中注意红色那部分Token验证成功的事件注册,其目的是认证成功之后,从JWT中取出必要信息构建当前用户上下文,这个上下文信息非常重要,但凡涉及到需要获取当前用户相关信息的部分,都要依赖它,后续文章中对应部分还会提及。
(4)登录并写入Token
/// <summary>
/// 登录
/// </summary>
/// <param name="userDto"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody]SysUserDto userDto)
{
var validateResult = await _accountService.ValidateCredentials(userDto.Account, userDto.Password);
if (!validateResult.Item1)
{
return new NotFoundObjectResult("用户名或密码错误");
} var user = validateResult.Item2;
var claims = new Claim[]
{
new Claim(ClaimTypes.NameIdentifier, user.Account),
new Claim(ClaimTypes.Name, user.Name),
new Claim(JwtRegisteredClaimNames.Email, user.Email),
new Claim(JwtRegisteredClaimNames.Sub, user.ID.ToString()),
new Claim(ClaimTypes.Role, user.RoleId)
}; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtConfig.SymmetricSecurityKey)); var token = new JwtSecurityToken(
issuer: _jwtConfig.Issuer,
audience: null,
claims: claims,
notBefore: DateTime.Now,
expires: DateTime.Now.AddHours(),
signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
); var jwtToken = new JwtSecurityTokenHandler().WriteToken(token); return new JsonResult(new { token = jwtToken });
}
(5)前端Token状态保存
一般来讲,在后端登录成功返回前端之后,前端需要保存此token以保持状态,否则一刷新全完蛋,那我们来看看前端怎么实现。由于前端项目引入了Vuex来保持状态,那api调用、状态操作自然就放在store中,我们来看看登录对应的store。打开前端源码,找到user这个store:
我们看到,登录完毕,调用SET_TOKEN这个mutation提交token状态变更保存Token,这个mutation及其背后的state如下如下:
同时,在登录action中,登录成功之后,我们还发现了一行代码:
此setToken引自前端工具类,auth.js,代码如下:
import Cookies from 'js-cookie' const TokenKey = 'ngcc_mis_token' export function getToken() {
return Cookies.get(TokenKey)
} export function setToken(token) {
return Cookies.set(TokenKey, token)
} export function removeToken() {
return Cookies.remove(TokenKey)
}
至此我们明白了前端的机制,把token写入Vuex状态的同时,再写入cookie。那这里问一句,只写入Vuex状态,行不行呢?不行,因为浏览器一刷新,所有前端对象就会销毁,包括Vuex对象,这样会导致前端丢失会话。
3、总结
以上就是系统认证的实现,大家摸清楚各种认证方案、优缺点、特点,多深入源码、机制,遇到问题自然会手到擒来。
Core + Vue 后台管理基础框架2——认证的更多相关文章
- Core + Vue 后台管理基础框架0——开篇
1.背景 最近,打算新开个项目,鉴于团队技术栈,选型.net core + vue,前后端分离.本打算捡现成的轮子的,github上大致逛了逛,总发现这样那样的不太适合心中那些“完美实践”,例如:Ab ...
- Core + Vue 后台管理基础框架3——后端授权
1.前言 但凡业务系统,授权是绕不开的一环.见过太多只在前端做菜单及按钮显隐控制,但后端裸奔的,觉着前端看不到,系统就安全,掩耳盗铃也好,自欺欺人也罢,这里不做评论.在.NET CORE中,也见过不少 ...
- Core + Vue 后台管理基础框架4——前端授权
1.前言 上篇,我们讲了后端的授权.与后端不同,前端主要是通过功能入口如菜单.按钮的显隐来控制授权的.具体来讲,就是根据指定用户的制定权限来加载对应侧边栏菜单和页面内的功能按钮.我们一个个来讲. 2. ...
- Core + Vue 后台管理基础框架9——统一日志
1.背景 前阵子有园友留言,提到日志相关的东西,同时,最近圈子里也有提到日志这个东西.一个充分.集中的统一日志平台还是很有必要的,否则系统出问题了只能靠猜或者干瞪眼.何谓充分,日志记录满足最低要求.出 ...
- Core + Vue 后台管理基础框架7——APM
1.前言 APM,又称应用性能统计,主要用来跟踪请求调用链,每个环节调用耗时,为我们诊断系统性能.定位系统问题提供了极大便利.本系统采用的是Elastic Stack体系中的APM,主要是之前部门搞P ...
- Core + Vue 后台管理基础框架8——Swagger文档
1.前言 作为前后端分离的项目,或者说但凡涉及到对外服务的后端,一个自描述,跟代码实时同步的文档是极其重要的.说到这儿,想起了几年前在XX速运,每天写完代码,还要给APP团队更新文档的惨痛经历.给人家 ...
- Core + Vue 后台管理基础框架1——运行系统
1.down源码 git clone https://github.com/KINGGUOKUN/SystemManagement.git,项目目录如下: 2.还原数据库 找到项目根目录下System ...
- hsweb 企业后台管理基础框架
hsweb 详细介绍 业务功能 现在: 权限管理: 权限资源-角色-用户. 配置管理: kv结构,自定义配置.可通过此功能配置数据字典. 脚本管理: 动态脚本,支持javascript,groovy, ...
- 如何在ASP.NET Core中实现一个基础的身份认证
注:本文提到的代码示例下载地址> How to achieve a basic authorization in ASP.NET Core 如何在ASP.NET Core中实现一个基础的身份认证 ...
随机推荐
- 74)PHP,Session的一些属性
(1) (2)有效期在 会话周期结束(就是将浏览器关闭前) (3)有效路径: 整站都有效 (4)有效域:当前域 (5)是否安全传输:否 (6)以上的session数据的特征都是由一个问题导致的,就 ...
- jenkins-自定义工作空间目录
- 从程序到系统:建立一个更智能的世界——记Joseph Sifakis“21世纪的计算”大会主题演讲
Sifakis"21世纪的计算"大会主题演讲" title="从程序到系统:建立一个更智能的世界--记Joseph Sifakis"21世纪的计算&q ...
- Java反射的实例
JAVA反射机制是在运行状态中,对于任意一个类,都能够得到这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法; 这种动态获取的信息以及动态调用对象的方法的功能称为ja ...
- labview学习——生产者/消费者(数据)(事件)
其主要的模型: 主要从以下几个方面理解: 1.可重入性 正常的labview是多线程设计语言,而我们在执行VI时的规则是通过VI的命名来分别调用实现的. 打开VI的Highlight调试工具,可以看出 ...
- SpringMVC学习笔记四:SimpleMappingExceptionResolver异常处理
SpringMVC的异常处理,SimpleMappingExceptionResolver只能简单的处理异常 当发生异常的时候,根据发生的异常类型跳转到指定的页面来显示异常信息 ExceptionCo ...
- python Dom
Dom(Document) 称为:文档对象模型,是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式.DOM把网页和脚本以及其他的编程语言联系了起 ...
- poi报表导出4.1.0版本工具类 导出并下载
这一段时间,由于项目上线基于稳定,所以我这边在基于我们一期迭代的分支上优化一部分我们之前没有做的功能,报表导出.本身之前用的是3.5的版本,但是由于同事要写导入,写的代码只有4.1.0的版本支持,所以 ...
- 使用Navicat for Oracle工具连接oracle出错:ORA-12737
今天上网的时候偶然发现了一款oracle的客户端的图形化管理和开发工具,当看到这个界面的时候,感觉很舒服,便上网搜了一下这个工具,看百度百科之后感觉很出乎我的意料,这个产品对于许多的数据库竟都有支持, ...
- linux vi命令详解及使用技巧
进入vi的命令vi filename :打开或新建文档,并将光标置于第一行首vi +n filename :打开文档,并将光标置于第n行首vi + filename :打开文档,并将光标置于最后一行首 ...