.NET Core 集成JWT认证

JWT(Json web token)就不用过多的介绍了,在 .NET Core 开发中使用JWT进行认证也是比较常见的,而且接入过程也比较简单,随便配置配置就好了。

要想使用JWT,仅仅只需要在项目中引用微软的一个认证组件。

Install-Package Microsoft.AspNetCore.Authentication.JwtBearer

然后将一些敏感数据可以放在配置文件appsettings.json中。

{"JWT": {"ClockSkew": 10,"ValidAudience": "https://meowv.com","ValidIssuer": "阿星Plus","IssuerSigningKey": "6Zi/5pifUGx1c+mYv+aYn1BsdXPpmL/mmJ9QbHVz6Zi/5pifUGx1c+mYv+aYn1BsdXPpmL/mmJ9QbHVz6Zi/5pifUGx1c+mYv+aYn1BsdXPpmL/mmJ9QbHVz6Zi/5pifUGx1cw==","Expires": 30}
}

Startup中添加配置并且使用

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{options.TokenValidationParameters = new TokenValidationParameters{ValidateIssuer = true,ValidateAudience = true,ValidateLifetime = true,ClockSkew = TimeSpan.FromSeconds(Convert.ToInt32(Configuration.GetSection("JWT")["ClockSkew"])),ValidateIssuerSigningKey = true,ValidAudience = Configuration.GetSection("JWT")["ValidAudience"],ValidIssuer = Configuration.GetSection("JWT")["ValidIssuer"],IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("JWT")["IssuerSigningKey"]))};});services.AddAuthorization();
app.UseAuthentication();
app.UseAuthorization();

这样一个简单的JWT配置就完成了,接下来新写一个接口去生成token。

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;namespace JsonWebTokenDemo.Controllers
{[Route("api/[controller]")][ApiController]public class AuthController : ControllerBase{public AuthController(IConfiguration configuration){Configuration = configuration;}public IConfiguration Configuration { get; }[HttpGet][Route("Token")]public string GenerateTokenAsync(string username, string password){if (username == "meowv" && password == "123"){var claims = new[] {new Claim(ClaimTypes.Name, username),new Claim(ClaimTypes.Email, "123@meowv.com"),new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddMinutes(Convert.ToInt32(Configuration.GetSection("JWT")["Expires"]))).ToUnixTimeSeconds()}"),new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}")};var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("JWT")["IssuerSigningKey"]));var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);var securityToken = new JwtSecurityToken(issuer: Configuration.GetSection("JWT")["ValidIssuer"],audience: Configuration.GetSection("JWT")["ValidAudience"],claims: claims,expires: DateTime.Now.AddMinutes(Convert.ToInt32(Configuration.GetSection("JWT")["Expires"])),signingCredentials: creds);var token = new JwtSecurityTokenHandler().WriteToken(securityToken);return token;}else{throw new Exception("账号密码错误");}}}
}

模拟用户登录,成功登录则去生成token,在实际应用中还可以对接第三方登录系统进行认证,调用接口看下效果。

可以看到第一个接口输入正确的账号密码,成功返回了token,第二个接口会抛出一个异常。

接下来去写两个接口,去验证一下token的使用是否正常,写一个需要授权的接口和一个不需要授权的接口。

[HttpGet]
[Authorize]
[Route("AuthorizeTest")]
public string AuthorizeTest()
{return "我是返回结果";
}[HttpGet]
[AllowAnonymous]
[Route("AllowAnonymousTest")]
public string AllowAnonymousTest()
{return "我是返回结果";
}

这两个接口的唯一区别就是,[Authorize][AllowAnonymous]

添加了 [Authorize]特性的表明是需要进行授权才可以访问此接口,而添加了[AllowAnonymous]特性则表明不需要授权谁都可以访问,同样调用看一下效果。

第一个接口没有返回出结果,可见生效了,此时调用的时候就需要带上我们前面生成的token成功授权后才能返回数据。

有时候当我们没有成功授权,会直接返回一个401的错误页面,如果需要自定义返回信息需要怎么做呢?

这个有好几种做法,可以用中间件,拦截器等等,不过这里推荐一种组件集成好的做法,直接上代码。

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{...options.Events = new JwtBearerEvents{OnChallenge = async context =>{context.HandleResponse();context.Response.ContentType = "application/json;charset=utf-8";context.Response.StatusCode = StatusCodes.Status401Unauthorized;await context.Response.WriteAsync("{\"message\":\"Unauthorized\",\"success\":false}");}};});

添加上面这段代码即可,await context.Response.WriteAsync()可以返回你自定义的错误消息,这里返回的是一个json字符串。

另外还有一种场景,默认我们拿到token进行授权访问,是需要在请求头中添加Authorization Bearer {token}这种方式的,如果我不想在请求头中使用要怎么做呢?比如我想将token放在URL参数中,或者cookie中?

同样也是可以的,而且实现方式也超级简单,看下面代码。

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{...options.Events = new JwtBearerEvents{...OnMessageReceived = async context =>{context.Token = context.Request.Query["token"];await Task.CompletedTask;}};});

这里演示了将token放在URL请求参数中,其它情况请根据实际开发场景进行修改即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307877.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode111. 二叉树的最小深度(层序遍历10)

一:题目 二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(n…

拥抱.NET 5,可以从这个极速开发的Web应用框架开始

今年年初,微软 .NET 程序管理总监 Scott 在博客中表示,发布 .NET 5 的首个预览版,并提供SDK 和运行库下载。Scott 表示,.NET 5 是 .NET Framework 和 .NET Core 的未来,最终将成为一个统一平台,.NET5 将包含…

组件库实战 | 教你如何设计Web世界中的表单验证

教你如何设计Web世界中的表单验证💬序言🗯️一、验证输入框ValidateInput1. 设计稿抢先知2. 简单的实现3. 抽象验证规则4. v-model5. 使用$attrs支持默认属性💭二、验证表单ValidateForm1. 组件需求分析2. 使用插槽 slot3. 父子组件通讯&…

leetcode101. 对称二叉树(两种做法)

一:题目 二:上码 方法一:队列 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int …

微服务架构下的测试策略

源宝导读:最近几年,微服务架构越来越火爆,逐渐被企业所采用。随着软件架构的变化,对应的软件测试策略需要作何调整呢?本文将介绍云客在微服务架构下的测试策略。一、云客测试策略模型策略分析行业内的测试策略是一个先…

leetcode222. 完全二叉树的节点个数(两种做法)

一:题目 二:今天不上菜 上码了 方法一:前序遍历 求解 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr)…

听红宝书译者谈Web视角下的前端开发

Web视角下的前端开发⏳序言⏰一、关于前端开发1. 起源、架构、变迁(1)起源(2)架构(3)变迁2. 前端应用的领域(1)所面向群体(2)所面向领域3. 语言、框架、工具4…

在家办公这半年,让我开始热爱生活

距离上次更新公众号已经过去一年多了,感觉自己成了“年更姚”。不过好在这个公众号的读者大多是同事朋友(加起来也没有多少好么喂),本身对我也没用太高的期待吧。今天想聊聊远程工作这件事。不过我并不想聊团队成员之间如何远程协…

每天都在红绿灯前面梭行,不如自己来实现个红绿灯?

用js实现一个交通灯🔇前言🔈一、需求分析 - 交通灯🔉二、实现版本1. 版本一:简单粗暴版2. 版本二:数据抽象版3. 版本三:过程抽象版4. 版本四:命令式和声明式🔊三、在线online&#x…

Git 常用操作 | 重写 commit 历史

当我们修改完代码,提交了一个 commit,然后发现改错了,怎么修正?这种情况分为两种:修正最近一次提交,和修正历史多个提交。修正最近一次提交如果发现刚刚提交的内容有错误,当场再修改一下再提交一…

leetcode257. 二叉树的所有路径(两种做法)

一:题目 二:上码 1:DFS /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), …

【LeetCode之C#解法】 移动零、爬楼梯

题目官网链接https://leetcode-cn.com/problems/move-zeroes/283. 移动零给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。示例:输入: [0,1,0,3,12]输出: [1,3,12,0,0]说明:必须在原数组上操作,不能拷…

幂等问题 vs 如何判断是否是4的幂

判断是否是4的幂🤹序言🚴一、需求分析 - 判断是否是4的幂等🤾二、实现版本1. 版本一:中规中矩法2. 版本二:按位与3. 版本三:按位与优化4. 版本四:正则匹配法⛹️三、结束语🤼往期推荐…

leetcode404. 左叶子之和

一:题目 二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(n…

切西瓜法实现微信抢红包功能

运用切西瓜法和栅栏法实现微信抢红包功能✅前言☑️一、需求分析 - 分红包问题🆙二、实现版本1. 版本一:切西瓜法2. 版本二:栅栏法✳️三、在线Online🆗四、结束语🆚往期推荐✅前言 在现实生活中,非常常见…

如何给扑克洗牌才能更公平?

如何给扑克牌洗牌才能更显公平性📻前言一、🎙️需求分析 - 洗牌问题二、💿实现版本1. 版本一:常规思维2. 版本二:验证公平性3. 版本三:交换法则三、📺在线Online四、📹结束语&#x…

这些年我是怎么自学成架构师的(转自知乎)

近日在知乎上一则关于程序员能否“自学成才”的问题,引发了激烈的讨论!各种各样的说法都有,最终变成程序员晒学习经历的帖子。作为十多年.NET技术老兵,纯自学成架构师,也来分享下观点:自学当然有效&#xf…

创新视角下的复盘 | 2021/08/01-2021/09/30

🗂️序言 七月份的时候第一次做月度复盘,发现如果只有每日计划,还是比较零散的。月度复盘可以更直观地看到自己的时间规划和及时纠正当下存在的一些问题。 在8-9月份中,有一半在暑假,一半开始于新学期。 &#x1f4…

TIOBE 9 月榜单:C#上涨1.18,Java 同比下滑3.18

喜欢就关注我们吧!TIOBE 已公布 2020 年 9 月的编程语言排行榜。C 近期发展状态不错,依旧在榜单中排第四,但排名比率保持增长,本月为 7.11%。2003 年是 C 的巅峰时期,当年 8 月,它的 TIOBE 排名峰值为 17.5…

储存引擎InnoDB 索引选择 为何是B+树 而不是 B树 哈希表

一:概述 首先需要澄清的一点是,MySQL 跟 B 树没有直接的关系,真正与 B 树有关系的是 MySQL 的默认存储引擎 InnoDB,MySQL 中存储引擎的主要作用是负责数据的存储和提取,除了 InnoDB 之外,MySQL 中也支持 MyISAM 作为表…