ASP.NET Core 8.0 WebApi 从零开始学习JWT登录认证

这篇具有很好参考价值的文章主要介绍了ASP.NET Core 8.0 WebApi 从零开始学习JWT登录认证。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

我一起写后端Api我都是直接裸连的,但是现在为了规范一些,我还是打算上一个JWT功能

相关链接

ASP.NET Web API 2系列(四):基于JWT的token身份认证方案

Jwt-dotnet github

Nuget选择

.net8 jwt,C#,asp.net,学习,后端
选好了模板,就进去看看号了,42M的下载量已经很高了,一般来说,只要超过500k的下载量,基本就是一个稳定的代码仓库了。

进去看看里面写的怎么样

.net8 jwt,C#,asp.net,学习,后端

可以看到写的还是比较清晰的

.net8 jwt,C#,asp.net,学习,后端

知识补充

JWT不是加密算法

JWT全名 JSON Web Token。Token这部分才是加密得出来的,JWT只是一个网页认证策略。

可逆加密和不可逆加密

无论是可逆加密还是不可逆加密,都需要一个自定义的【Key】来辅助加密。可逆加密就类似于一元二次方程,key就类似于修改方程各项的系数,【Key=125】得到【x^2+2x+5】。我的原文是【1】,得到的密文就是计算后的结果【8】。所以加密比解密要方便。

不可逆加密就是不能逆向解决的方程,比如高阶方程【x^7- x^3 +5x-3】,正向好算,逆向基本不可解。

所以现实使用的时候,可逆加密一般是解密后使用。因为可逆,所以可以用于复杂的敏感信息。
不可逆加密是判断加密后的的密文是否相同,比如密码,是不能泄漏的,所以我们的密码只能重置,因为系统也不知道原密码是什么。

普通Jwt(不推荐)

项目环境

  • visual studio 2022
  • .net core 8.0
  • win 10

Nuget

.net8 jwt,C#,asp.net,学习,后端
.net8 jwt,C#,asp.net,学习,后端

最小JWT测试

我们先不管JWT是如何添加到ASP.NET Core里面的,我们先测试JWT的加密和登录验证的功能。

/// <summary>
/// 加密密钥
/// </summary>
private static readonly string jwtKey = "TokenKey";

public record UserTest(string Name,string Account,string Password);

static void Main(string[] args)
{

    UserTest userTest = new UserTest("小王","admin","1dixa0d");
    Console.WriteLine("原文");
    Console.WriteLine(JsonConvert.SerializeObject(userTest));//{"Name":"小王","Account":"admin","Password":"1dixa0d"}

    var encoder = GetEncoder();
    string jwtToken = encoder.Encode(userTest,jwtKey);
    Console.WriteLine("加密");
    Console.WriteLine(jwtToken);//eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJOYW1lIjoi5bCP546LIiwiQWNjb3VudCI6ImFkbWluIiwiUGFzc3dvcmQiOiIxZGl4YTBkIn0.C_tlDhHpkjAkJpRRdnqz6Jn2FmP0qONAI4oNl8Ye9wM

    var decoder =  GetDecoder();
    var decodeData =  decoder.Decode(jwtToken,jwtKey);
    Console.WriteLine("解密");
    Console.WriteLine(decodeData);//{"Name":"小王","Account":"admin","Password":"1dixa0d"}


    Console.WriteLine("Hello, World!");
}

/// <summary>
/// 获取加密解密
/// </summary>
/// <returns></returns>
public static IJwtEncoder GetEncoder()
{
    IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//加密方式
    IJsonSerializer serializer = new JsonNetSerializer();//序列化Json
    IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//base64加解密
    IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);//JWT编码
    return encoder;
}

/// <summary>
/// 获取解密密钥
/// </summary>
/// <returns></returns>
public static IJwtDecoder GetDecoder()
{
    IJsonSerializer serializer = new JsonNetSerializer();
    IDateTimeProvider provider = new UtcDateTimeProvider();
    IJwtValidator validator = new JwtValidator(serializer, provider);
    IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
    IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
    IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
    return decoder;
}

.net8 jwt,C#,asp.net,学习,后端
这里的JWT的加密解密算法是可以自己搭配的,选择加密算法,这里我就不展开了。详细可以看官方文档
.net8 jwt,C#,asp.net,学习,后端

在WebApi中简单使用

首先我们之前用到了可逆的加密和解密。那我们就需要用一个判断是否过期的类

public class UserJwtLogin
{
    /// <summary>
    /// 用户Id,因为数据库的Id是唯一的,不会重复
    /// </summary>
    public long UserId { get; set; }    

    /// <summary>
    /// 过期时间
    /// </summary>
    public DateTime ExpireTime { get; set; }
}

详细的解决方案就在这个文章里面了,我就不照抄了,拾人牙慧。

ASP.NET Web API 2系列(四):基于JWT的token身份认证方案

我这里是这么写的

新建一个JwtHelper

public static class JwtHelper
{

    private static readonly string JwtKey = "这里填你的密钥";
    /// <summary>
    /// 获取加密解密
    /// </summary>
    /// <returns></returns>
    private static IJwtEncoder GetEncoder()
    {
        IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//加密方式
        IJsonSerializer serializer = new JsonNetSerializer();//序列化Json
        IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//base64加解密
        IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);//JWT编码
        return encoder;
    }

    /// <summary>
    /// 获取解密密钥
    /// </summary>
    /// <returns></returns>
    private static IJwtDecoder GetDecoder()
    {
        IJsonSerializer serializer = new JsonNetSerializer();
        IDateTimeProvider provider = new UtcDateTimeProvider();
        IJwtValidator validator = new JwtValidator(serializer, provider);
        IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
        IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
        IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
        return decoder;
    }

    /// <summary>
    /// 加密
    /// </summary>
    public static string Encode(object payload)
    {
        var encoder = GetEncoder();
        var token = encoder.Encode(payload, JwtKey);
        return token;
    }

    /// <summary>
    /// 解密
    /// </summary>
    public static T Decode<T>(string token)
    {
        var decoder = GetDecoder();
        var data =  decoder.Decode(token,JwtKey);
        var res  = JsonConvert.DeserializeObject<T>(data);
        return res;
    }

    /// <summary>
    /// 解密,只返回Json文本
    /// </summary>
    /// <param name="token"></param>
    /// <returns></returns>
    public static string Decode(string token)
    {

        var decoder = GetDecoder();
        var data = decoder.Decode(token, JwtKey);
        return data;
    }

}

两个实体类

   public class UserJwtLogin
   {
       /// <summary>
       /// 用户Id,因为数据库的Id是唯一的,不会重复
       /// </summary>
       public long UserId { get; set; }    

       /// <summary>
       /// 过期时间
       /// </summary>
       public DateTime ExpireTime { get; set; }
   }
public class WebMsg
{

    public int Code { get; set; } = 200;

    public bool Success { get; set; } = true;

    public object Data {get; set; }

    public string Msg { get; set; } = "操作成功!";


    public WebMsg()
    {

    }


    public WebMsg(object data)
    {
        Data = data;
    }
}

简单使用

/// <summary>
/// Jwt登录
/// </summary>
[Route("api/[controller]/[action]")]
[ApiController]
public class LoginController : ControllerBase
{
	//这个是我的Nlog配置,这里不做展开
    private NlogService nlogService;

    public LoginController(NlogService nlogService)
    {
        this.nlogService = nlogService;
    }



    /// <summary>
    /// JWT登录
    /// </summary>
    /// <param name="username">账号</param>
    /// <param name="password">密码</param>
    /// <returns></returns>
    [HttpGet]
    public WebMsg Login(string username, string password)
    {

        if (username == null || password == null)
        {
            return new WebMsg()
            {
                Msg = "登录信息为空",
                Success = false,
            };
        }
        if (username == "admin" && password == "123456")
        {
			//这里是模拟拿到数据库的User表的Id
            var pyload = new UserJwtLogin()
            {
                UserId = 291,
                ExpireTime = DateTime.Now.AddDays(1)
            };
            var token = JwtHelper.Encode(pyload);
            return new WebMsg(token);
        }
        else
        {
            return new WebMsg()
            {
                Msg = "登录失败,账号或者密码错误",
                Success = false,
            };
        }

    }

    /// <summary>
    /// Jwt解密
    /// </summary>
    /// <param name="token"></param>
    /// <returns></returns>
    [HttpGet]
    public WebMsg Decode(string token)
    {
        try
        {
            var res = JwtHelper.Decode(token);
            return new WebMsg(res);
        }
        catch (Exception ex)
        {
            nlogService.Error("登录解析失败:" + token);
            nlogService.Error(ex.Message);
            return new WebMsg() { 
                Msg = "登录解析失败:" + token,
                Success = false,
            };
        }
    }
}

运行结果

.net8 jwt,C#,asp.net,学习,后端

{
  "code": 200,
  "success": true,
  "data": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJVc2VySWQiOjI5MSwiRXhwaXJlVGltZSI6IjIwMjQtMDMtMTRUMTM6MjE6MzYuNjE3NDk0KzA4OjAwIn0.sxh9sM4gQoCfFfim-MQSsHqDQX3Dji3FZaEu4t06D1s",
  "msg": "操作成功!"
}

.net8 jwt,C#,asp.net,学习,后端

{
  "code": 200,
  "success": true,
  "data": "{\"UserId\":291,\"ExpireTime\":\"2024-03-14T13:21:36.617494+08:00\"}",
  "msg": "操作成功!"
}

WebApi 授权,博客太老了,尝试失败

这里我们就用简单的授权,复杂的授权可以自己去看微软官方文档

ASP.NET Core 中的简单授权

.net8 jwt,C#,asp.net,学习,后端

然后我发现.net core 8.0的认证方式好像变了,我按照博客的写法发现不让我重写了
.net8 jwt,C#,asp.net,学习,后端
这个方法是.net framework上面用的,.net core 用不了。我想还是算了,用.net core 的方法好了
.net8 jwt,C#,asp.net,学习,后端

.net8 jwt,C#,asp.net,学习,后端
.net8 jwt,C#,asp.net,学习,后端

WebApi .net core 8.0 最新版Jwt (微软官方集成)

我看了一天的博客,终于解决了JWT认证的问题。

在没有 ASP.NET CoreIdentity的情况下使用cookie身份验证

ASP.NET Core 6.0 添加 JWT 认证和授权

.Net Core WebApi集成JWT实现身份认证

.net8 jwt,C#,asp.net,学习,后端

重新新建一个Webapi

这里我就不多说了

.NET Core webapi 从零开始在IIS上面发布后端接口

我们还是要改一下的,因为之前的我测试的时候,发现Builder里面的代码实在是太多了,这里我们分开一下


using Microsoft.OpenApi.Models;
using System.Reflection;

namespace JtwTestWebApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
            var MyPolicy = "MyPolicy";
            // Add services to the container.

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();
            //为了防止配套太多,代码混乱。这里自定义了一个方法
            AddMyService(builder);
            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                
            }
            app.UseSwagger();
            app.UseSwaggerUI();
            app.UseStatusCodePagesWithRedirects("/swagger/index.html");
            app.UseHttpsRedirection();

            app.UseAuthorization();


            app.MapControllers();

            app.Run();
        }

        /// <summary>
        /// 为了防止代码过于臃肿,将新的配置放在这里写
        /// </summary>
        /// <param name="builder"></param>
        public static void AddMyService(WebApplicationBuilder builder)
        {
            builder.Services.AddCors(options =>
            {
                options.AddPolicy("MyPolicy", policy =>
                {
                    policy.AllowAnyHeader().AllowAnyOrigin().AllowAnyMethod();
                });
            });
            builder.Services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "v1",
                    Title = "API标题",
                    Description = $"API描述,v1版本"
                });
                var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                //IncludeXmlComments 第二参数 true 则显示 控制器 注释
                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename), true);
            });
        }
    }
}

简单Controller

public class WebMsg
{

    public object Data { get; set; }

    public bool Success { get; set; } = true;

    public string Msg { get; set; } = "操作成功!";

    public WebMsg()
    {

    }

    public WebMsg(object data)
    {
        Data = data;
    }
}
/// <summary>
/// 测试控制器
/// </summary>
[Route("api/[controller]/[action]")]
[ApiController]
public class TestController : ControllerBase
{
    /// <summary>
    /// 测试返回值
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public WebMsg GetTest()
    {
        return new WebMsg("测试返回值");
    }

}

.net8 jwt,C#,asp.net,学习,后端

最简单的Jwt认证

我们知道Jwt其实就是生成和验证两个功能。微软把这个功能集成到一个JwtBearer库里面了。

.net8 jwt,C#,asp.net,学习,后端
为了方便Json打印,添加个Newtonsoft
.net8 jwt,C#,asp.net,学习,后端

获取JwtConfig

我们在appsetting.json里面添加

  "JwtConfig": {
    "SecretKey": "123123123123", // 密钥   可以是guid 也可以是随便一个字符串
    "Issuer": "XiaoWang", // 颁发者
    "Audience": "XiaoWang", // 接收者
    "Expired": 30 // 过期时间(30min)
  }

.net8 jwt,C#,asp.net,学习,后端

 public class JwtConfig
 {
     /// <summary>
     /// 密钥
     /// </summary>
     public string SecretKey { get; set; }   

     /// <summary>
     /// 发布者
     /// </summary>
     public string Issuer { get; set; }

     /// <summary>
     /// 接受者
     /// </summary>
     public string Audience { get; set; }

     /// <summary>
     /// 过期时间(min)
     /// </summary>
     public int Expired { get; set; }
 }

获取Config

var jwtConfig = new JwtConfig();
builder.Configuration.Bind("JwtConfig",jwtConfig);

.net8 jwt,C#,asp.net,学习,后端
.net8 jwt,C#,asp.net,学习,后端

新建JwtHelper类

 public class JwtHelper
 {

     public JwtConfig JwtConfig { get; set; }
     public JwtHelper()
     {

     }

     /// <summary>
     /// 添加Jwt服务
     /// </summary>
     public void AddJwtService()
     {

     }

     /// <summary>
     /// 返回
     /// </summary>
     /// <returns></returns>
     public string GetJwtToken()
     {
         //简单测试一下
         var token = JsonConvert.SerializeObject(JwtConfig);
         return token;
     }


 }

我们应该使用Ioc的方式注入JwtHelper

var jwtConfig = new JwtConfig();
builder.Configuration.Bind("JwtConfig",jwtConfig);
var jwtHelper = new JwtHelper() {
    JwtConfig = jwtConfig
};
//将JwtHelper添加到Services里面
builder.Services.AddSingleton<JwtHelper>(jwtHelper);

.net8 jwt,C#,asp.net,学习,后端

然后在控制器里面获取Token

/// <summary>
/// 测试控制器
/// </summary>
[Route("api/[controller]/[action]")]
[ApiController]
public class TestController : ControllerBase
{
    private JwtHelper jwtHelper;

    /// <summary>
    /// 通过Ioc得到Jwt
    /// </summary>
    /// <param name="jwtHelper"></param>
    public TestController(JwtHelper jwtHelper) {
        this.jwtHelper = jwtHelper;
    }
    /// <summary>
    /// 测试返回值
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public WebMsg GetTest()
    {
        return new WebMsg("测试返回值");
    }


    /// <summary>
    /// 获取JwtToken
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public WebMsg GetJwtToken()
    {
        var token = jwtHelper.GetJwtToken();
        return new WebMsg(token);
    }
}

.net8 jwt,C#,asp.net,学习,后端
接下来我们修改一下GetJwtToken这个函数即可

完善JwtConfig

using Microsoft.IdentityModel.Tokens;
using System.Text;

namespace JtwTestWebApi.Models
{
    public class JwtConfig
    {
        /// <summary>
        /// 密钥
        /// </summary>
        public string SecretKey { get; set; }

        /// <summary>
        /// 发布者
        /// </summary>
        public string Issuer { get; set; }

        /// <summary>
        /// 接受者
        /// </summary>
        public string Audience { get; set; }

        /// <summary>
        /// 过期时间(min)
        /// </summary>
        public int Expired { get; set; }

        /// <summary>
        /// 生效时间
        /// </summary>
        public DateTime NotBefore => DateTime.Now;

        /// <summary>
        /// 过期时间
        /// </summary>
        public DateTime Expiration => DateTime.Now.AddMinutes(Expired);

        /// <summary>
        /// 密钥Bytes
        /// </summary>
        private SecurityKey SigningKey => new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey));

        /// <summary>
        /// 加密后的密钥,使用HmacSha256加密
        /// </summary>
        public SigningCredentials SigningCredentials =>
            new SigningCredentials(SigningKey, SecurityAlgorithms.HmacSha256);
    }
}

在JwtHelper里面使用

/// <summary>
/// 最简单的JwtToken
/// </summary>
/// <returns></returns>
public string GetJwtToken()
{
    var claims = new List<Claim>();
    var jwtSecurityToken = new JwtSecurityToken(
            JwtConfig.Issuer,
            JwtConfig.Audience,
            claims,
            JwtConfig.NotBefore,
            JwtConfig.Expiration,
            JwtConfig.SigningCredentials
        );
    var token = new JwtSecurityTokenHandler().WriteToken( jwtSecurityToken );
    return token;
}
       

运行报错,说明密钥的长度太短了,我们加长一下
.net8 jwt,C#,asp.net,学习,后端
.net8 jwt,C#,asp.net,学习,后端
返回成功!

.net8 jwt,C#,asp.net,学习,后端

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE3MTAzODUyODgsImV4cCI6MTcxMDM4NzA4OCwiaXNzIjoiWGlhb1dhbmciLCJhdWQiOiJYaWFvV2FuZyJ9.v7UbQOba7VoNgoiRsoIQkFJKQTFBMLJlYEKBIfdFV4o

授权

加密了,肯定要有对应的授权

在JwtConfig里面添加对应的授权

public class JwtConfig
{
    /// <summary>
    /// 密钥
    /// </summary>
    public string SecretKey { get; set; }

    /// <summary>
    /// 发布者
    /// </summary>
    public string Issuer { get; set; }

    /// <summary>
    /// 接受者
    /// </summary>
    public string Audience { get; set; }

    /// <summary>
    /// 过期时间(min)
    /// </summary>
    public int Expired { get; set; }

    /// <summary>
    /// 生效时间
    /// </summary>
    public DateTime NotBefore => DateTime.Now;

    /// <summary>
    /// 过期时间
    /// </summary>
    public DateTime Expiration => DateTime.Now.AddMinutes(Expired);

    /// <summary>
    /// 密钥Bytes
    /// </summary>
    private SecurityKey SigningKey => new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey));

    /// <summary>
    /// 加密后的密钥,使用HmacSha256加密
    /// </summary>
    public SigningCredentials SigningCredentials =>
        new SigningCredentials(SigningKey, SecurityAlgorithms.HmacSha256);

    /// <summary>
    /// 认证用的密钥
    /// </summary>
    public SymmetricSecurityKey SymmetricSecurityKey => new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey));
}

.net8 jwt,C#,asp.net,学习,后端

在JwtHelper中

/// <summary>
/// 添加Jwt服务
/// </summary>
public void AddJwtService(IServiceCollection services)
{
    services.AddAuthentication(option =>
    {
        //认证middleware配置
        option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            //Token颁发机构
            ValidIssuer = JwtConfig.Issuer,
            //颁发给谁
            ValidAudience = JwtConfig.Audience,
            //这里的key要进行加密
            IssuerSigningKey = JwtConfig.SymmetricSecurityKey,
            //是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
            ValidateLifetime = true,
        };
    });
}

调用JwtHelper

  var jwtConfig = new JwtConfig();
  builder.Configuration.Bind("JwtConfig",jwtConfig);
  var jwtHelper = new JwtHelper() {
      JwtConfig = jwtConfig
  };
  //将JwtHelper添加到Services里面
  builder.Services.AddSingleton<JwtHelper>(jwtHelper);
  jwtHelper.AddJwtService(builder.Services);

在app中启用

            app.UseHttpsRedirection();
            app.UseAuthentication();//要在授权之前认证,这个和[Authorize]特性有关
            app.UseAuthorization();

一定要在za之前使用ca
.net8 jwt,C#,asp.net,学习,后端

授权测试

我们接口最好单独开一个获取Token的接口

TestController

using JtwTestWebApi.Models;
using JtwTestWebApi.Utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace JtwTestWebApi.Controllers
{
    /// <summary>
    /// 测试控制器
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        private JwtHelper jwtHelper;

        /// <summary>
        /// 通过Ioc得到Jwt
        /// </summary>
        /// <param name="jwtHelper"></param>
        public TestController(JwtHelper jwtHelper) {
            this.jwtHelper = jwtHelper;
        }
        /// <summary>
        /// 测试返回值
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public WebMsg GetTest()
        {
            return new WebMsg("测试返回值");
        }


        /// <summary>
        /// 获取JwtToken
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public WebMsg GetJwtToken()
        {
            var token = jwtHelper.GetJwtToken();
            return new WebMsg(token);
        }

        /// <summary>
        /// 可以在方法前面加Authorize
        /// </summary>
        /// <returns></returns>
        [Authorize]
        [HttpGet]
        public WebMsg GetByJwt()
        {
            return new WebMsg("Jwt测试成功!");
        }
    }
}

JtwTestWebApi

如果我们在类前面添加了[Authorize],下面全部的接口都有Jwt认证。想放开Jtw认证,使用[AllowAnonymous]标记方法即可

using JtwTestWebApi.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace JtwTestWebApi.Controllers
{
    /// <summary>
    /// Jwt测试类
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Authorize]
    public class JwtTestController : ControllerBase
    {
        /// <summary>
        /// 不需要Jwt
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpGet]
        public WebMsg NoJwtGet()
        {
            return new WebMsg("我不需要Jwt");
        }


        /// <summary>
        /// 需要Jwt
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public WebMsg JwtGet()
        {
            return new WebMsg("我需要Jwt");
        }
    }
}

认证失败的结果

.net8 jwt,C#,asp.net,学习,后端

能通过Jwt的请求

既然我们拦截了请求,我们也得对符合规范的请求放行。那什么样的请求能放行呢?在Header中的【Authorization】中添加【Bearer {token}】才能放行。

PostMan测试

.net8 jwt,C#,asp.net,学习,后端
.net8 jwt,C#,asp.net,学习,后端

测试成功!
.net8 jwt,C#,asp.net,学习,后端

过期测试

.NetCore JWT token过期时间设置

Jwt的过期是由两个数据综合相加的。一个是生成Token的过期时间

.net8 jwt,C#,asp.net,学习,后端
一个是缓冲时间,默认5分钟。因为服务器的时间可能不同步。

.net8 jwt,C#,asp.net,学习,后端
所以总过期时间=过期时间+缓冲时间

.net8 jwt,C#,asp.net,学习,后端
为了更简单的获取Token,我们直接把返回的Token自带[Bearer ]这个前缀好了

Swagger 全局Header

在JwtHelper中添加全局静态方法

/// <summary>
/// Swagger添加Jwt功能
/// </summary>
/// <param name="options"></param>
public static void SwaggerAddJwtHeader(SwaggerGenOptions options)
{
    options.AddSecurityRequirement(new OpenApiSecurityRequirement()
        {
            {
                new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference {
                        Type = ReferenceType.SecurityScheme,
                        Id = "Bearer",
                    }
                },
            new string[] { }
            }
        });
    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Description = "JWT授权(数据将在请求头中进行传输) 在下方输入Bearer {token} 即可,注意两者之间有空格",
        Name = "Authorization",//jwt默认的参数名称
        In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
        Type = SecuritySchemeType.ApiKey,
        BearerFormat = "JWT",
        Scheme = "Bearer"
    });
}

.net8 jwt,C#,asp.net,学习,后端
.net8 jwt,C#,asp.net,学习,后端
.net8 jwt,C#,asp.net,学习,后端
.net8 jwt,C#,asp.net,学习,后端
.net8 jwt,C#,asp.net,学习,后端

获取Jwt中的信息

因为我们的Jwt是自带【Bearer 】这个请求头的,所以去掉前面的头,里面其实是可以解密的

 /// <summary>
 /// 获取Jwt的信息
 /// </summary>
 /// <param name="request"></param>
 /// <returns></returns>
 public IEnumerable<Claim> Decode(HttpRequest request)
 {
     
     var authorization = request.Headers["Authorization"].ToString();
     //因为我们的Jwt是自带【Bearer 】这个请求头的,所以去掉前面的头
     var auth = authorization.Split(" ")[1];
     var handler = new JwtSecurityTokenHandler();
     //反解密,获取其中的Claims
     var payload = handler.ReadJwtToken(auth).Payload;
     var claims = payload.Claims;
     return claims;
 }

解密能拿到是因为我们加密的时候就已经放进去了

 /// <summary>
 /// 添加claims信息
 /// </summary>
 /// <param name="claims"></param>
 /// <returns></returns>
 public string GetJwtToken(List<Claim> claims)
 {
     var jwtSecurityToken = new JwtSecurityToken(
             JwtConfig.Issuer,
             JwtConfig.Audience,
             claims,
             JwtConfig.NotBefore,
             JwtConfig.Expiration,
             JwtConfig.SigningCredentials
         );
     var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
     token = "Bearer " + token;
     return token;
 }
 /// <summary>
 /// 获取JwtToken
 /// </summary>
 /// <returns></returns>
 [HttpGet]
 public WebMsg GetJwtToken2()
 {
 	//我们加密的时候,就放进去了一些额外的信息
     var token = jwtHelper.GetJwtToken(new List<Claim>()
     {
         new Claim("UserId","2"),
         new Claim("UserName","3")
     });
     return new WebMsg(token);
 }
/// <summary>
/// 可以在方法前面加Authorize
/// </summary>
/// <returns></returns>
[Authorize]
[HttpGet]
public WebMsg GetByJwt()
{
	//获取解密后的Claim
    var dic = jwtHelper.Decode(this.Request);
    return new WebMsg("Jwt测试成功!");
}

.net8 jwt,C#,asp.net,学习,后端
这样我们就可以把一些比较隐私的数据放在里面,比如用户Id,这样防止泄漏。

简单封装一下

using JtwTestWebApi.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace JtwTestWebApi.Utils
{
    public class JwtHelper
    {

        public JwtConfig JwtConfig { get; set; }
        public JwtHelper()
        {

        }

        /// <summary>
        /// 添加Jwt服务
        /// </summary>
        public void AddJwtService(IServiceCollection services)
        {
            services.AddAuthentication(option =>
            {
                //认证middleware配置
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    //Token颁发机构
                    ValidIssuer = JwtConfig.Issuer,
                    //颁发给谁
                    ValidAudience = JwtConfig.Audience,
                    //这里的key要进行加密
                    IssuerSigningKey = JwtConfig.SymmetricSecurityKey,
                    //是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
                    ValidateLifetime = true,
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateIssuerSigningKey = true,
                    RequireExpirationTime = true,
                };
            });
        }

        /// <summary>
        /// 最简单的JwtToken
        /// </summary>
        /// <returns></returns>
        public string GetJwtToken()
        {
            var claims = new List<Claim>();
            var jwtSecurityToken = new JwtSecurityToken(
                    JwtConfig.Issuer,
                    JwtConfig.Audience,
                    claims,
                    JwtConfig.NotBefore,
                    JwtConfig.Expiration,
                    JwtConfig.SigningCredentials
                );
            var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
            token = "Bearer " + token;
            return token;
        }

        /// <summary>
        /// 添加claims信息
        /// </summary>
        /// <param name="claims"></param>
        /// <returns></returns>
        public string GetJwtToken(List<Claim> claims)
        {
            var jwtSecurityToken = new JwtSecurityToken(
                    JwtConfig.Issuer,
                    JwtConfig.Audience,
                    claims,
                    JwtConfig.NotBefore,
                    JwtConfig.Expiration,
                    JwtConfig.SigningCredentials
                );
            var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
            token = "Bearer " + token;
            return token;
        }

        /// <summary>
        /// UserModel类Token
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public string GetJwtToken(JwtUserModel user)
        {
            var claims = new List<Claim>() {
                new Claim("UserId",user.UserId.ToString()),
                new Claim("UserName",user.UserName),
                new Claim("UserType",user.UserType.ToString()),
            };
            return GetJwtToken(claims);
        }

        /// <summary>
        /// Swagger添加Jwt功能
        /// </summary>
        /// <param name="options"></param>
        public static void SwaggerAddJwtHeader(SwaggerGenOptions options)
        {
            options.AddSecurityRequirement(new OpenApiSecurityRequirement()
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference {
                                Type = ReferenceType.SecurityScheme,
                                Id = "Bearer",
                            }
                        },
                    new string[] { }
                    }
                });
            options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            {
                Description = "JWT授权(数据将在请求头中进行传输) 在下方输入Bearer {token} 即可,注意两者之间有空格",
                Name = "Authorization",//jwt默认的参数名称
                In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
                Type = SecuritySchemeType.ApiKey,
                BearerFormat = "JWT",
                Scheme = "Bearer"
            });
        }

        /// <summary>
        /// 获取Jwt的信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public IEnumerable<Claim> Decode(HttpRequest request)
        {

            var authorization = request.Headers["Authorization"].ToString();
            //因为我们的Jwt是自带【Bearer 】这个请求头的,所以去掉前面的头
            var auth = authorization.Split(" ")[1];
            var handler = new JwtSecurityTokenHandler();
            //反解密,获取其中的Claims
            var payload = handler.ReadJwtToken(auth).Payload;
            var claims = payload.Claims;
            return claims;
        }

        /// <summary>
        /// 解析得到User
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public JwtUserModel DecodeToUser(HttpRequest request)
        {
            var claims = Decode(request);
            var user = new JwtUserModel()
            {
                UserId = claims.Where(t => t.Type == "UserId").First().Value,
                UserName = claims.Where(t => t.Type == "UserName").First().Value,
                UserType = claims.Where(t => t.Type == "UserType").First().Value
            };
            return user;
        }
    }
}

[HttpGet]
public WebMsg GetJwtToken3()
{
    var token = jwtHelper.GetJwtToken(new JwtUserModel()
    {
        UserName = "小王",
        UserId = "32",
        UserType = "admin"
    });
    return new WebMsg(token);
}
[Authorize]
[HttpGet]
public WebMsg GetByJwt3()
{
    var dic = jwtHelper.DecodeToUser(this.Request);

    return new WebMsg("Jwt测试成功!");
}

运行得到结果
.net8 jwt,C#,asp.net,学习,后端

Jwt授权模式基础讲解

介绍三种授权方式(Policy、Role、Scheme),Scheme这种用的太少了,我们就简单讲解一下Policy和Role这两种方式。Policy和Role的核心就在于我们封装Token的时候添加的Claim对象。大家看到这里就会发现,其实Jwt的核心就是装包和拆包。网页请求Token的时候拿到了个包裹,网页发送Http的时候解开这个包裹。

我写了一会,感觉有点累了。这里有个别人写好的代码,有兴趣的自己去看吧。

ASP.NET Core 6.0 添加 JWT 认证和授权

简单的【角色授权】

获取不同权限的Token

获取不同权限的Token

/// <summary>
/// 获取Role = admin的Token
/// </summary>
/// <returns></returns>
[HttpGet]
public WebMsg GetJwtToken_Admin()
{
    var token = jwtHelper.GetJwtToken(new List<Claim>()
    {
        new Claim(ClaimTypes.Role,"admin")
    });

    return new WebMsg(token);
}
/// <summary>
/// 获取Role = user
/// </summary>
/// <returns></returns>
[HttpGet]
public WebMsg GetJwtToken_User()
{
    var token = jwtHelper.GetJwtToken(new List<Claim>()
    {
        new Claim(ClaimTypes.Role,"user")
    });

    return new WebMsg(token);
}

/// <summary>
/// 获取Role = admin和user
/// </summary>
/// <returns></returns>
[HttpGet]
public WebMsg GetJwtToken_UserAndAdmin()
{
    var token = jwtHelper.GetJwtToken(new List<Claim>()
    {
        new Claim(ClaimTypes.Role,"user"),
        new Claim(ClaimTypes.Role,"admin")
    });

    return new WebMsg(token);
}
不同权限的jwt认证
/// <summary>
/// 需要role=admin
/// </summary>
/// <returns></returns>
[HttpGet]
[Authorize(Roles = "admin")]
public WebMsg AdminGet()
{
    return new WebMsg("admin");
}
/// <summary>
/// role=user
/// </summary>
/// <returns></returns>
[HttpGet]
[Authorize(Roles = "user")]
public WebMsg UserGet()
{
    return new WebMsg("user");
}

/// <summary>
/// role = admin或user
/// </summary>
/// <returns></returns>
[HttpGet]
[Authorize(Roles = "admin,user")]
public WebMsg AdminOrUserGet()
{
    return new WebMsg("admin or user");
}
/// <summary>
/// role=admin和user
/// </summary>
/// <returns></returns>
[HttpGet]
[Authorize(Roles = "admin")]
[Authorize(Roles = "user")]
public WebMsg AdminAndUserGet()
{
    return new WebMsg("admin and user");
}

这里推荐使用enum枚举类型,这样不会出现拼写错误

封装好的代码

using Microsoft.IdentityModel.Tokens;
using System.Text;

namespace JtwTestWebApi.Models
{
    public class JwtConfig
    {
        /// <summary>
        /// 密钥
        /// </summary>
        public string SecretKey { get; set; }

        /// <summary>
        /// 发布者
        /// </summary>
        public string Issuer { get; set; }

        /// <summary>
        /// 接受者
        /// </summary>
        public string Audience { get; set; }

        /// <summary>
        /// 过期时间(min)
        /// </summary>
        public int Expired { get; set; }

        /// <summary>
        /// 生效时间
        /// </summary>
        public DateTime NotBefore => DateTime.Now;

        /// <summary>
        /// 过期时间
        /// </summary>
        public DateTime Expiration => DateTime.Now.AddMinutes(Expired);

        /// <summary>
        /// 密钥Bytes
        /// </summary>
        private SecurityKey SigningKey => new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey));

        /// <summary>
        /// 加密后的密钥,使用HmacSha256加密
        /// </summary>
        public SigningCredentials SigningCredentials =>
            new SigningCredentials(SigningKey, SecurityAlgorithms.HmacSha256);

        /// <summary>
        /// 认证用的密钥
        /// </summary>
        public SymmetricSecurityKey SymmetricSecurityKey => new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey));



    }
}

using JtwTestWebApi.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace JtwTestWebApi.Utils
{
    public class JwtHelper
    {

        public JwtConfig JwtConfig { get; set; }
        public JwtHelper()
        {

        }

        /// <summary>
        /// 添加Jwt服务
        /// </summary>
        public void AddJwtService(IServiceCollection services)
        {
            services.AddAuthentication(option =>
            {
                //认证middleware配置
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    //Token颁发机构
                    ValidIssuer = JwtConfig.Issuer,
                    //颁发给谁
                    ValidAudience = JwtConfig.Audience,
                    //这里的key要进行加密
                    IssuerSigningKey = JwtConfig.SymmetricSecurityKey,
                    //是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
                    ValidateLifetime = true,
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateIssuerSigningKey = true,
                    RequireExpirationTime = true,
                };
            });
        }

        /// <summary>
        /// 最简单的JwtToken
        /// </summary>
        /// <returns></returns>
        public string GetJwtToken()
        {
            var claims = new List<Claim>();
            var jwtSecurityToken = new JwtSecurityToken(
                    JwtConfig.Issuer,
                    JwtConfig.Audience,
                    claims,
                    JwtConfig.NotBefore,
                    JwtConfig.Expiration,
                    JwtConfig.SigningCredentials
                );
            var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
            token = "Bearer " + token;
            return token;
        }

        /// <summary>
        /// 添加claims信息
        /// </summary>
        /// <param name="claims"></param>
        /// <returns></returns>
        public string GetJwtToken(List<Claim> claims)
        {
            var jwtSecurityToken = new JwtSecurityToken(
                    JwtConfig.Issuer,
                    JwtConfig.Audience,
                    claims,
                    JwtConfig.NotBefore,
                    JwtConfig.Expiration,
                    JwtConfig.SigningCredentials
                );
            var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
            token = "Bearer " + token;
            return token;
        }

        /// <summary>
        /// UserModel类Token
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public string GetJwtToken(JwtUserModel user)
        {
            var claims = new List<Claim>() {
                new Claim("UserId",user.UserId.ToString()),
                new Claim("UserName",user.UserName),
                new Claim("UserType",user.UserType.ToString()),
            };
            return GetJwtToken(claims);
        }

        /// <summary>
        /// Swagger添加Jwt功能
        /// </summary>
        /// <param name="options"></param>
        public static void SwaggerAddJwtHeader(SwaggerGenOptions options)
        {
            options.AddSecurityRequirement(new OpenApiSecurityRequirement()
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference {
                                Type = ReferenceType.SecurityScheme,
                                Id = "Bearer",
                            }
                        },
                    new string[] { }
                    }
                });
            options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            {
                Description = "JWT授权(数据将在请求头中进行传输) 在下方输入Bearer {token} 即可,注意两者之间有空格",
                Name = "Authorization",//jwt默认的参数名称
                In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
                Type = SecuritySchemeType.ApiKey,
                BearerFormat = "JWT",
                Scheme = "Bearer"
            });
        }

        /// <summary>
        /// 获取Jwt的信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public IEnumerable<Claim> Decode(HttpRequest request)
        {

            var authorization = request.Headers["Authorization"].ToString();
            //因为我们的Jwt是自带【Bearer 】这个请求头的,所以去掉前面的头
            var auth = authorization.Split(" ")[1];
            var handler = new JwtSecurityTokenHandler();
            //反解密,获取其中的Claims
            var payload = handler.ReadJwtToken(auth).Payload;
            var claims = payload.Claims;
            return claims;
        }

        /// <summary>
        /// 解析得到User
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public JwtUserModel DecodeToUser(HttpRequest request)
        {
            var claims = Decode(request);
            var user = new JwtUserModel()
            {
                UserId = claims.Where(t => t.Type == "UserId").First().Value,
                UserName = claims.Where(t => t.Type == "UserName").First().Value,
                UserType = claims.Where(t => t.Type == "UserType").First().Value
            };
            return user;
        }
    }
}

namespace JtwTestWebApi.Models
{
    public class JwtUserModel
    {

        public string UserId { get; set; }

        public string UserName { get; set; }

        public string UserType { get; set; }
    }
}


using JtwTestWebApi.Models;
using JtwTestWebApi.Utils;
using Microsoft.Extensions.Configuration;
using Microsoft.OpenApi.Models;
using System.IdentityModel.Tokens.Jwt;
using System.Reflection;

namespace JtwTestWebApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
            var MyPolicy = "MyPolicy";
            // Add services to the container.

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();
            //为了防止配套太多,代码混乱。这里自定义了一个方法
            AddMyService(builder);
            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                
            }
            app.UseSwagger();
            app.UseSwaggerUI();
            app.UseStatusCodePagesWithRedirects("/swagger/index.html");
            app.UseHttpsRedirection();
            app.UseAuthentication();//要在授权之前认证,这个和[Authorize]特性有关
            app.UseAuthorization();


            app.MapControllers();

            app.Run();
        }

        /// <summary>
        /// 为了防止代码过于臃肿,将新的配置放在这里写
        /// </summary>
        /// <param name="builder"></param>
        public static void AddMyService(WebApplicationBuilder builder)
        {
            #region 默认的Webapi配置
            builder.Services.AddCors(options =>
            {
                options.AddPolicy("MyPolicy", policy =>
                {
                    policy.AllowAnyHeader().AllowAnyOrigin().AllowAnyMethod();
                });
            });
            builder.Services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "v1",
                    Title = "API标题",
                    Description = $"API描述,v1版本"
                });
                var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                //IncludeXmlComments 第二参数 true 则显示 控制器 注释
                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename), true);
                JwtHelper.SwaggerAddJwtHeader(options);
            });
            #endregion 

            #region 添加Jwt服务
            var jwtConfig = new JwtConfig();
            builder.Configuration.Bind("JwtConfig",jwtConfig);
            var jwtHelper = new JwtHelper() {
                JwtConfig = jwtConfig
            };
            //将JwtHelper添加到Services里面
            builder.Services.AddSingleton<JwtHelper>(jwtHelper);
            jwtHelper.AddJwtService(builder.Services);
            #endregion

        }
    }
}

appsettings.json中添加

  "JwtConfig": {
    "SecretKey": "lisheng741@qq.comlisheng741@qq.com",
    "Issuer": "WebAppIssuer",
    "Audience": "WebAppAudience",
    "Expired": 30 // 过期时间(30min)
  }

总结

Jwt其实也不是特别难,就是第一次配置的时候容易被绕晕。Jwt的策略我暂时先跳过了,对于解决普通问题一般来说已经够用了。文章来源地址https://www.toymoban.com/news/detail-844995.html

到了这里,关于ASP.NET Core 8.0 WebApi 从零开始学习JWT登录认证的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ASP.NET Core SingleR Core:WebApi + .net 客户端开发

    我之前稍微研究了一下SignalR Core。用起来还行。简单来说SignalR就是用来解决实时通讯的问题的。 ASP.NET Core SingleR:初次体验和简单项目搭建 SignalR支持三种客户端,C#,Java,JavaScirpt。基本够用了。本身就是微软开发的,肯定支持自己的语言。因为是Websocket的上层封装,所以也要支

    2024年01月20日
    浏览(48)
  • Asp.net core Webapi 如何执行定时任务?

    在计算机系统中,定时执行一些后台任务是很常见的场景,比如定时发送邮件、备份数据等等。 那么,.NET 技术如何通过编程灵活地实现项目里复杂的自定义任务呢? 如果是 Windows 生态,通常来说,可以有这些方式: 编写一个程序,通过 Windows 内置的任务计划来定时执行。

    2024年02月04日
    浏览(28)
  • .net 温故知新【14】:Asp.Net Core WebAPI 缓存

    缓存指在中间层中存储数据的行为,该行为可使后续数据检索更快。 从概念上讲,缓存是一种性能优化策略和设计考虑因素。 缓存可以显著提高应用性能,方法是提高不常更改(或检索成本高)的数据的就绪性。 在最新的缓存控制规范文件RFC9111中,详细描述了浏览器缓存和

    2024年02月05日
    浏览(37)
  • ASP.NET core WebApi Cors跨域解决

    我用了最新版的Asp.net webapi ,在csdn上面搜跨域如何解决的时候,发现csdn上面对于.NET技术讨论不是很多。没办法,只能面向官方文档和GitHub编程了。 前面两个已经放弃维护了,我们就不用了。用最新的webApi 我们引入了最新的api后可以在官方网址上查看文档(有些地址是gitH

    2024年04月29日
    浏览(35)
  • asp.net core webapi如何执行周期性任务

    新建asp.net core webapi项目,使用Nuget搜索安装Quartz包。 注意:定时执行时间格式,参考连接:https://www.cnblogs.com/wudequn/p/8506938.html 在IIS中找到这个站点所用的程序池,点击“高级设置…” 在打开的列表中更改以下设置: 回收——固定时间间隔(分钟) 改为 0 ——虚拟/专用内存

    2024年02月13日
    浏览(29)
  • .net 温故知新【17】:Asp.Net Core WebAPI 中间件

    到这篇文章为止,关于.NET \\\"温故知新\\\"系列的基础知识就完结了,从这一系列的系统回顾和再学习,对于.NET core、ASP.NET CORE又有了一个新的认识。 不光是从使用,还包括这些知识点的原理,虽然深入原理谈不上,但对于日常使用也够了,我想的是知其然,知其所以然。 在实际

    2024年01月18日
    浏览(34)
  • .net 温故知新【11】:Asp.Net Core WebAPI 入门使用及介绍

    在Asp.Net Core 上面由于现在前后端分离已经是趋势,所以asp.net core MVC用的没有那么多,主要以WebApi作为学习目标。 我使用的是VS2022, .Net 7版本。 在创建界面有几项配置: 配置Https 启用Docker 使用控制器 启用OpenAPI支持 不使用顶级语句 其中配置Https 是WebApi是否使用https协议,启

    2024年02月07日
    浏览(27)
  • ASP.NET Core MVC 使用 JWT 的示例

    创建一个 ASP.NET Core MVC 项目。 添加 NuGet 包: Microsoft.AspNetCore.Authentication.JwtBearer:用于支持 JWT 的身份验证。 System.IdentityModel.Tokens.Jwt:用于生成和验证 JWT。 在 Startup.cs 文件中做如下修改: 请注意,在上述代码中,您需要将以下参数替换为实际的值: \\\"your_issuer\\\" :发行者的标

    2024年02月13日
    浏览(26)
  • 前后端分离,Asp.net core webapi 简单 2 步,轻松配置跨域

    可以说,前后端分离已经成为当今信息系统项目开发的主流软件架构模式,微服务的出现,让前后端分离发展更是迅速,大量优秀的前端框架如 vue.js、react 的出现,也让前后端分离趋势加快。 所谓的前后端分离软件架构模式,就是指将前端和后端的开发完全分离,后端负责

    2024年01月17日
    浏览(30)
  • ASP.NET Core WebAPI如何获得远程文件返回文件流给前端?

      项目采用的是前后端分离的模式,后端使用ASP.NET Core WebAPI方式,将文件流返回给前端。   前端采用的是Vue技术栈,采用的是axios调用后端接口。前端无法获得fileName需要修改后端ASP.NET Core WebAPI项目中的【Startup.cs】文件。  修改ConfigureServices方法中的AddCors。   代码示例:

    2024年02月15日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包