vue token刷新_.NET Core+Vue后台管理基础框架—认证

(给DotNet加星标,提升.Net技能)

转自:GUOKUN cnblogs.com/guokun/p/12483215.html

一、前言

这块儿当时在IdentityServer4和JWT之间犹豫了一下,后来考虑到现状,出于3个原因,暂时放弃了IdentityServer4选择了JWT:

1、目前这个前端框架更适配JWT;

2、前后端分离的项目,如果上IdentityServer4,还要折腾点儿工作,比如前端配置、多余的回调等;

3、跨度太大,团队、系统、历史数据接入都是问题,解决是可以解决,但时间有限,留待后续吧;

当然,只是暂时放弃,理想中的最佳实践还是IdentityServer4做统一鉴权的。

二、JWT认证实现

1、Common项目下定义JWTConfig配置对象

44f93e0dd4a19d3c3125a290b8531e62.png

2、系统配置文件中增加JWT参数配置

9887bd71daa310a6fdb6f976b631bd59.png

此处配置与(1)中的配置对象是对应的。

3、JWT处理程序及相关服务注册

services.Configure(Configuration.GetSection("JWT"));var jwtConfig = Configuration.GetSection("JWT").Get();
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(5)
};
options.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{var userContext = context.HttpContext.RequestServices.GetService();var claims = context.Principal.Claims;
userContext.ID = long.Parse(claims.First(x => x.Type == JwtRegisteredClaimNames.Sub).Value);
userContext.Account = claims.First(x => x.Type == ClaimTypes.NameIdentifier).Value;
userContext.Name = claims.First(x => x.Type == ClaimTypes.Name).Value;
userContext.Email = claims.First(x => x.Type == JwtRegisteredClaimNames.Email).Value;
userContext.RoleId = claims.First(x => x.Type == ClaimTypes.Role).Value;return Task.CompletedTask;
}
};
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

上述代码中注意红色那部分Token验证成功的事件注册,其目的是认证成功之后,从JWT中取出必要信息构建当前用户上下文,这个上下文信息非常重要,但凡涉及到需要获取当前用户相关信息的部分,都要依赖它,后续文章中对应部分还会提及。

4、登录并写入Token

/// 
/// 登录
///
///
///
[AllowAnonymous]
[HttpPost("login")]
public async TaskLogin([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(2),
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:

ed313ae4b3757c87acdb6b3204f7e4da.png

我们看到,登录完毕,调用SET_TOKEN这个mutation提交token状态变更保存Token,这个mutation及其背后的state如下如下:

0f0630766dc0ee7ce9f988ab5abd61c8.png

同时,在登录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对象,这样会导致前端丢失会话。同时,我们再扩展深入下,假如这里我们要做点单登录,不借助IdentityServer4这种统一认证平台的话,怎么做呢?其实很简单,这里写入cookie改为写入localstoage这种浏览器中可以跨域共享的存储就可以了。

三、总结

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

推荐阅读   点击标题可跳转 .NET Core+Vue后台管理基础框架 C#桌面开发的未来WebWindow 如何提升.NET控制台应用体验?

看完本文有收获?请转发分享给更多人

关注「DotNet」加星标,提升.Net技能 

158e44c77841d7db47e89e93bb843287.png

好文章,我在看❤️

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值