ASP.NET Core Web API + Angular 仿B站(三)后台配置 JWT 的基于 token 的验证
前言:
本系列文章主要为对所学 Angular 框架的一次微小的实践,对 b站页面作简单的模仿。
本系列文章主要参考资料:
微软文档: https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/?view=aspnetcore-2.1&tabs=windows
Angular 文档: https://angular.cn/tutorial
Typescript 文档: https://www.typescriptlang.org/docs/home.html
本章额外参考文档:
https://www.dotnettricks.com/learn/angular/token-based-authentication-json-web-token-aspnet-core
https://tools.ietf.org/html/rfc7519
此系列皆使用 C#+Typescript+Angular+EF Core 作为开发环境,使用 VSCode 对 Angular 进行开发同时作为命令行启动器,使用 VS2017 对 ASP.NET Core 进行开发。如果有什么问题或者意见欢迎在留言区进行留言。
如果图片看不清的话请在新窗口打开图片或保存本地查看。
项目 github 地址:https://github.com/NanaseRuri/FakeBilibili
本章内容:建立 ASP.NET Core Web API + Angular 验证
一、配置 ASP.NET Core
首先在 appsetting.json 中添加字段:
"Jwt": {
"Key": "TempPrivateSecretKey",
"Issuer": "localhost:5001"
},

然后在 ConfigureServices 方法中为服务器添加 Jwt 服务:
确定服务的行为:ValidateIssuer = true 验证生成 JWT 的服务器信息;ValidateAudience = true 验证接收 JWT 的服务器;ValidateLifetime = true 检查 JWT 的过期时间;ValidateIssuerSigningKey = true 检查 JWT 的签名。
配置服务的参数: ValidIssuer 待验证的 Jwt 的生成方, ValidAudience 待验证的接收方。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
});
二、创建提供标识的控制器和方法
准备工作:
在此仅提供 ID + 密码 的验证方式,因而新建一个视图模型:
public class LoginModel
{
public string Account { get; set; }
public string Password { get; set; }
public LoginType LoginType { get; set; }
}
创建一个用来加密密码的接口 IEncrypt ,该接口为之前 Encryptor 类方法的提取,然后在 Encryptor 中继承该接口:
public interface IEncrypt
{
string Encrypt(string password,string salt);
}
在 Configure 方法中对该接口进行注册,确保整个应用程序生存期内使用的为同一实例:
services.AddScoped<IEncrypt, Encryptor>();
然后创建一个 API 控制器,在构造函数中对各项参数进行注入:
[Route("api/[controller]")]
[ApiController]
public class AccountController : ControllerBase
{
private IConfiguration _config;
private UserIdentityDbContext _identityDbContext;
private IEncrypt _encryptor;
public AccountController(IConfiguration config, IEncrypt encryptor, UserIdentityDbContext identityDbContext)
{
_config = config;
_identityDbContext = identityDbContext;
_encryptor = encryptor;
}
}
逻辑编写:
对用户进行验证,如果验证通过则生成 Jwt:
[HttpPost]
[Route("Login")]
public async Task<IActionResult> Login(LoginModel account)
{
var user = await ValidateUser(account);
if (user != null)
{
var tokenString = GenerateJsonWebToken(user);
return Ok(new { token = tokenString });
}
return Unauthorized();
}
验证方法:
判断用户是否存在 => 获取盐值 => 进行加密后验证密码是否正确:
async Task<UserIdentity> ValidateUser(LoginModel account)
{
UserIdentity user = await GetUser(account);
if (user == null)
{
return null;
}
var hashPassword = _encryptor.Encrypt(account.Password, user.Salt);
if (user.Password == hashPassword)
{
return user;
}
return null;
}
通过正则表达式判断输入的登录方式的类型以通过不同字段获取用户:
async Task<UserIdentity> GetUser(LoginModel account)
{
string regexId = @"^\d+$";
string regexUserName = @"^\w+[\d\w]*$";
string regexEmail = @"[a-zA-Z\d]+@[a-zA-Z\d]+.";
UserIdentity user = new UserIdentity();
if (Regex.IsMatch(account.Account,regexId))
{
user = await _identityDbContext.Users.FirstOrDefaultAsync(u => u.Id == Int32.Parse(account.Account));
}
else if (Regex.IsMatch(account.Account,regexUserName))
{
user = await _identityDbContext.Users.FirstOrDefaultAsync(u => u.UserName == account.Account);
}
else if (Regex.IsMatch(account.Account,regexEmail))
{
user = await _identityDbContext.Users.FirstOrDefaultAsync(u => u.Email == account.Account);
}
return user;
}
生成 Jwt 的方法:
由于使用的是 Sha256 签名算法,此处 SymmetricSecurityKey 要求 _config["Jwt:Key"] 不少于 16 位,否则在最后一步中会抛出异常。
string GenerateJsonWebToken(UserIdentity user)
{
//定义密钥
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
//定义要使用的密钥和进行哈希计算的算法
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
//定义待添加 Jwt 的 payload 字段
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
//定义 Jwt 的 payload 字段
var token = new JwtSecurityToken(
issuer: _config["Jwt:Issuer"],
audience: _config["Jwt:Issuer"],
claims: claims,
expires: DateTime.Now.AddMinutes(),
signingCredentials: credentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
运行程序,在 Postman 中对该方法进行测试:


将验证成功时返回的令牌放到 jwt.io 中进行检测:https://jwt.io/#encoded-jwt


ASP.NET Core Web API + Angular 仿B站(三)后台配置 JWT 的基于 token 的验证的更多相关文章
- ASP.NET Core Web API + Angular 仿B站(一) 目的分析以及创建 WebAPI + Angular7 项目
前言: 本系列文章主要为对所学 Angular 框架的一次微小的实践,对 b站页面作简单的模仿. 本系列文章主要参考资料: 微软文档: https://docs.microsoft.com/zh-cn ...
- ASP.NET Core Web API + Angular 仿B站(二)后台模型创建以及数据库的初始化
前言: 本系列文章主要为对所学 Angular 框架的一次微小的实践,对 b站页面作简单的模仿. 本系列文章主要参考资料: 微软文档: https://docs.microsoft.com/zh-cn ...
- 在ASP.NET Core Web API中为RESTful服务增加对HAL的支持
HAL(Hypertext Application Language,超文本应用语言)是一种RESTful API的数据格式风格,为RESTful API的设计提供了接口规范,同时也降低了客户端与服务 ...
- ASP.NET Core Web API 索引 (更新Identity Server 4 视频教程)
GraphQL 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(上) 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(下) [视频] 使用ASP.NET C ...
- asp.net core web api 生成 swagger 文档
asp.net core web api 生成 swagger 文档 Intro 在前后端分离的开发模式下,文档就显得比较重要,哪个接口要传哪些参数,如果一两个接口还好,口头上直接沟通好就可以了,如果 ...
- ASP.NET Core Web API中带有刷新令牌的JWT身份验证流程
ASP.NET Core Web API中带有刷新令牌的JWT身份验证流程 翻译自:地址 在今年年初,我整理了有关将JWT身份验证与ASP.NET Core Web API和Angular一起使用的详 ...
- 使用 Swagger 自动生成 ASP.NET Core Web API 的文档、在线帮助测试文档(ASP.NET Core Web API 自动生成文档)
对于开发人员来说,构建一个消费应用程序时去了解各种各样的 API 是一个巨大的挑战.在你的 Web API 项目中使用 Swagger 的 .NET Core 封装 Swashbuckle 可以帮助你 ...
- 在ASP.NET Core Web API上使用Swagger提供API文档
我在开发自己的博客系统(http://daxnet.me)时,给自己的RESTful服务增加了基于Swagger的API文档功能.当设置IISExpress的默认启动路由到Swagger的API文档页 ...
- Docker容器环境下ASP.NET Core Web API应用程序的调试
本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Docker容器环境下,对ASP.NET Core Web API应用程序进行调试.在 ...
随机推荐
- UVA 11888 - Abnormal 89's(Manachar)
UVA 11888 - Abnormal 89's option=com_onlinejudge&Itemid=8&page=show_problem&category=524 ...
- JS控制input 文本框只允许输入汉字
onblur="value=value.replace(/[^/u4E00-/u9FA5]/g,'')" onbeforepaste="clipboardData.set ...
- Redis 过期键的设置、获取和删除过期时间
Redis 过期键的设置.获取和删除过期时间 转自http://blog.51cto.com/littledevil/1813956 设置过期 默认情况下键是没有生存时间的,也就是永不过期,除非清空内 ...
- iframe仿ajax图片上传
1.前台页面: iframe_upload.html <html> <body> <form action="upload.php" id=" ...
- js中变量的声明
大家都知道js中变量的声明是要提前的,下面有4个样例: 1.if(!"t" in window){ var t = 1; } alert(t);答案是undefine ...
- ElasticSearch(八)关于document的一些知识点
先查看一条数据: GET /ecommerce/product/5 { "_index" : "ecommerce", "_type" : ...
- 正则表达式测试工具之Regex Match Tracer
下载地址:http://www.regex-match-tracer.com/downloads 使用示例1:匹配 使用示例2:替换
- ABAP抓取异常 try ,endtry.
DATA: O_CX TYPE REF TO CX_ROOT. TRY . MOVE LS_UPLOAD-MENGE TO LS_OUTPUT-MENGE. CATCH CX_ROOT INTO O_ ...
- git (转载)
文章转载 一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的 ...
- HDU5015 233 Matrix —— 矩阵快速幂
题目链接:https://vjudge.net/problem/HDU-5015 233 Matrix Time Limit: 10000/5000 MS (Java/Others) Memor ...