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. jenkins-自定义工作空间目录

  2. Python迭代器和关键字 global ,nonlocal

    1.关键字 global : 可以修改全局变量 可以在局部作用域声明一个全局变量,剪切 : 此时局部作用域没有该变量,全局作用域中有 name = 1 def func(): global name ...

  3. 数字签名和数字证书等openssl加密基本术语

    openssl 算法基础 1.1 对称算法 : 密钥相同,加密解密使用同一密钥 1.2 摘要算法:无论用户输入的数据什么长度,输出的都是固定长度的密文:即信息摘要,可用于判断数据的完整性:目前常用的有 ...

  4. 为Nginx启用目录浏览功能

    今天工作需要,要给客户提供一个patch的下载地址,于是想用nginx的目录浏览功能来做,需要让客户看到指定一个目录下的文件列表,然后让他自己来选择该下载那个文件: 我们都知道在apache下可以配置 ...

  5. ip获取到城市

    <?phpfunction GetIP() {    if ($_SERVER["HTTP_X_FORWARDED_FOR"])        $ip = $_SERVER[ ...

  6. string删除与查找erase,find

    s.erase( 指针位置 , 删除长度 ) 返回值修改后的string对象引用 find(string, int):第一个参数用来指示要查找的字符,第二个参数用来表示从字符串的何处开始查找子串(默认 ...

  7. python的IO

    格式化输出 格式化输出是指通过print()等函数向指定的地方(比如屏幕)输出指定格式的内容 格式: age = 18 name = "xiaohua" print("我 ...

  8. npm(classnames) 更灵活使用类名

    npm install classnames --save import classNames from 'classnames'; const inputCls = classNames({ [st ...

  9. 手机预装APP“死灰复燃”,这颗“毒瘤”到底怎么了

    ​ ​ 离全新智能手机集中发布的8月底.9月初这个时间段越来越近了,iPhone 8等重磅新机也为互联网媒体贡献了足够的流量和热度.但就在大众聚焦于新机时,一个困扰很多人的问题再度冒出头--智能手机上 ...

  10. C++走向远洋——59(项目三、图形面积、抽象类)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...