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、总结

  以上就是系统认证的实现,大家摸清楚各种认证方案、优缺点、特点,多深入源码、机制,遇到问题自然会手到擒来。

SET_TOKEN

Core + Vue 后台管理基础框架2——认证的更多相关文章

  1. Core + Vue 后台管理基础框架0——开篇

    1.背景 最近,打算新开个项目,鉴于团队技术栈,选型.net core + vue,前后端分离.本打算捡现成的轮子的,github上大致逛了逛,总发现这样那样的不太适合心中那些“完美实践”,例如:Ab ...

  2. Core + Vue 后台管理基础框架3——后端授权

    1.前言 但凡业务系统,授权是绕不开的一环.见过太多只在前端做菜单及按钮显隐控制,但后端裸奔的,觉着前端看不到,系统就安全,掩耳盗铃也好,自欺欺人也罢,这里不做评论.在.NET CORE中,也见过不少 ...

  3. Core + Vue 后台管理基础框架4——前端授权

    1.前言 上篇,我们讲了后端的授权.与后端不同,前端主要是通过功能入口如菜单.按钮的显隐来控制授权的.具体来讲,就是根据指定用户的制定权限来加载对应侧边栏菜单和页面内的功能按钮.我们一个个来讲. 2. ...

  4. Core + Vue 后台管理基础框架9——统一日志

    1.背景 前阵子有园友留言,提到日志相关的东西,同时,最近圈子里也有提到日志这个东西.一个充分.集中的统一日志平台还是很有必要的,否则系统出问题了只能靠猜或者干瞪眼.何谓充分,日志记录满足最低要求.出 ...

  5. Core + Vue 后台管理基础框架7——APM

    1.前言 APM,又称应用性能统计,主要用来跟踪请求调用链,每个环节调用耗时,为我们诊断系统性能.定位系统问题提供了极大便利.本系统采用的是Elastic Stack体系中的APM,主要是之前部门搞P ...

  6. Core + Vue 后台管理基础框架8——Swagger文档

    1.前言 作为前后端分离的项目,或者说但凡涉及到对外服务的后端,一个自描述,跟代码实时同步的文档是极其重要的.说到这儿,想起了几年前在XX速运,每天写完代码,还要给APP团队更新文档的惨痛经历.给人家 ...

  7. Core + Vue 后台管理基础框架1——运行系统

    1.down源码 git clone https://github.com/KINGGUOKUN/SystemManagement.git,项目目录如下: 2.还原数据库 找到项目根目录下System ...

  8. hsweb 企业后台管理基础框架

    hsweb 详细介绍 业务功能 现在: 权限管理: 权限资源-角色-用户. 配置管理: kv结构,自定义配置.可通过此功能配置数据字典. 脚本管理: 动态脚本,支持javascript,groovy, ...

  9. 如何在ASP.NET Core中实现一个基础的身份认证

    注:本文提到的代码示例下载地址> How to achieve a basic authorization in ASP.NET Core 如何在ASP.NET Core中实现一个基础的身份认证 ...

随机推荐

  1. Linux SSH 允许root用户远程登录和无密码登录

    1. 允许root用户远程登录 修改ssh服务配置文件 sudo vi /etc/ssh/sshd_config调整PermitRootLogin参数值为yes,如下图: 2. 允许无密码登录同上,修 ...

  2. 计算机BIOS的简单设置(要安装Linux需关闭Security Boot选项)

    计算机BIOS的简单设置(要安装Linux需关闭Security Boot选项) 发布时间:2016-12-07 22:46:19来源:linux网站作者:乐百川 BIOS是什么 BIOS全称是基本输 ...

  3. django框架基础-视图系统-长期维护

    ##################   什么是视图?     ####################### 视图: 1,一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受W ...

  4. Offer垂青于有准备的人——微软亚洲研究院实习生们的就业分享

    编者按:一年一度的"求职大战"又拉开了序幕,如何在求职中掌握主动,更好地展现自己,最后抓住Offer?且听微软亚洲研究院三位实习生慢慢道来,Offer总会垂青于有准备的人. 廖振, ...

  5. sql 优化之8个尽量

    查询语句的优化是SQL效率优化的一个方式,可以通过优化sql语句来尽量使用已有的索引,避免全表扫描,从而提高查询效率.最近在对项目中的一些sql进行优化,总结整理了一些方法. 1.在表中建立索引,优先 ...

  6. 每个月执行一次任务,保存90天的mongo日志数据

    用mongo 的dump 和 restore实现 shell版 #!/bin/bash mongodump --host -d lewifi -c auditOrigData -q {}} -o ~/ ...

  7. Linux启动初始化配置文件浅析

    转自:http://blog.51cto.com/19055/1144600 1)/etc/profile   登录时,会执行. 全局(公有)配置,不管是哪个用户,登录时都会读取该文件. (2)/ec ...

  8. IP地址结构分类(包括主机号和网络好计算)

    IP地址:互联网上的每个接口的唯一标识. 长度:32bit. 五类不同的互联网地址格式: 各类IP地址范围: 点分十进制:32位的地址通常写成四个十进制数,其中每个整数对应一个字节. 主机号和网络的计 ...

  9. 《hdu 免费馅饼》

    题目描述 免费馅饼 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  10. jquery mobile AJAX特性的陷阱

    简单情况是 MVC 重定向,URL不变 试了N种方式,跳来跳去,无解,服务端跳,写JS跳,生成跳转中间页跳.失败 后来一看,明明已经跳到新页了,样式什么还是原页的,有点火大了. 出去溜一圈,喝杯水,和 ...