国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

ASP.NET Core 8.0 WebApi 從零開始學(xué)習(xí)JWT登錄認(rèn)證

這篇具有很好參考價值的文章主要介紹了ASP.NET Core 8.0 WebApi 從零開始學(xué)習(xí)JWT登錄認(rèn)證。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

我一起寫后端Api我都是直接裸連的,但是現(xiàn)在為了規(guī)范一些,我還是打算上一個JWT功能

相關(guān)鏈接

ASP.NET Web API 2系列(四):基于JWT的token身份認(rèn)證方案

Jwt-dotnet github

Nuget選擇

.net8 jwt,C#,asp.net,學(xué)習(xí),后端
選好了模板,就進(jìn)去看看號了,42M的下載量已經(jīng)很高了,一般來說,只要超過500k的下載量,基本就是一個穩(wěn)定的代碼倉庫了。

進(jìn)去看看里面寫的怎么樣

.net8 jwt,C#,asp.net,學(xué)習(xí),后端

可以看到寫的還是比較清晰的

.net8 jwt,C#,asp.net,學(xué)習(xí),后端

知識補充

JWT不是加密算法

JWT全名 JSON Web Token。Token這部分才是加密得出來的,JWT只是一個網(wǎng)頁認(rèn)證策略。

可逆加密和不可逆加密

無論是可逆加密還是不可逆加密,都需要一個自定義的【Key】來輔助加密??赡婕用芫皖愃朴谝辉畏匠?,key就類似于修改方程各項的系數(shù),【Key=125】得到【x^2+2x+5】。我的原文是【1】,得到的密文就是計算后的結(jié)果【8】。所以加密比解密要方便。

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

所以現(xiàn)實使用的時候,可逆加密一般是解密后使用。因為可逆,所以可以用于復(fù)雜的敏感信息。
不可逆加密是判斷加密后的的密文是否相同,比如密碼,是不能泄漏的,所以我們的密碼只能重置,因為系統(tǒng)也不知道原密碼是什么。

普通Jwt(不推薦)

項目環(huán)境

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

Nuget

.net8 jwt,C#,asp.net,學(xué)習(xí),后端
.net8 jwt,C#,asp.net,學(xué)習(xí),后端

最小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,學(xué)習(xí),后端
這里的JWT的加密解密算法是可以自己搭配的,選擇加密算法,這里我就不展開了。詳細(xì)可以看官方文檔
.net8 jwt,C#,asp.net,學(xué)習(xí),后端

在WebApi中簡單使用

首先我們之前用到了可逆的加密和解密。那我們就需要用一個判斷是否過期的類

public class UserJwtLogin
{
    /// <summary>
    /// 用戶Id,因為數(shù)據(jù)庫的Id是唯一的,不會重復(fù)
    /// </summary>
    public long UserId { get; set; }    

    /// <summary>
    /// 過期時間
    /// </summary>
    public DateTime ExpireTime { get; set; }
}

詳細(xì)的解決方案就在這個文章里面了,我就不照抄了,拾人牙慧。

ASP.NET Web API 2系列(四):基于JWT的token身份認(rèn)證方案

我這里是這么寫的

新建一個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,因為數(shù)據(jù)庫的Id是唯一的,不會重復(fù)
       /// </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")
        {
			//這里是模擬拿到數(shù)據(jù)庫的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,
            };
        }
    }
}

運行結(jié)果

.net8 jwt,C#,asp.net,學(xué)習(xí),后端

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

.net8 jwt,C#,asp.net,學(xué)習(xí),后端

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

WebApi 授權(quán),博客太老了,嘗試失敗

這里我們就用簡單的授權(quán),復(fù)雜的授權(quán)可以自己去看微軟官方文檔

ASP.NET Core 中的簡單授權(quán)

.net8 jwt,C#,asp.net,學(xué)習(xí),后端

然后我發(fā)現(xiàn).net core 8.0的認(rèn)證方式好像變了,我按照博客的寫法發(fā)現(xiàn)不讓我重寫了
.net8 jwt,C#,asp.net,學(xué)習(xí),后端
這個方法是.net framework上面用的,.net core 用不了。我想還是算了,用.net core 的方法好了
.net8 jwt,C#,asp.net,學(xué)習(xí),后端

.net8 jwt,C#,asp.net,學(xué)習(xí),后端
.net8 jwt,C#,asp.net,學(xué)習(xí),后端

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

我看了一天的博客,終于解決了JWT認(rèn)證的問題。

在沒有 ASP.NET CoreIdentity的情況下使用cookie身份驗證

ASP.NET Core 6.0 添加 JWT 認(rèn)證和授權(quán)

.Net Core WebApi集成JWT實現(xiàn)身份認(rèn)證

.net8 jwt,C#,asp.net,學(xué)習(xí),后端

重新新建一個Webapi

這里我就不多說了

.NET Core webapi 從零開始在IIS上面發(fā)布后端接口

我們還是要改一下的,因為之前的我測試的時候,發(fā)現(xiàn)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標(biāo)題",
                    Description = $"API描述,v1版本"
                });
                var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                //IncludeXmlComments 第二參數(shù) 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,學(xué)習(xí),后端

最簡單的Jwt認(rèn)證

我們知道Jwt其實就是生成和驗證兩個功能。微軟把這個功能集成到一個JwtBearer庫里面了。

.net8 jwt,C#,asp.net,學(xué)習(xí),后端
為了方便Json打印,添加個Newtonsoft
.net8 jwt,C#,asp.net,學(xué)習(xí),后端

獲取JwtConfig

我們在appsetting.json里面添加

  "JwtConfig": {
    "SecretKey": "123123123123", // 密鑰   可以是guid 也可以是隨便一個字符串
    "Issuer": "XiaoWang", // 頒發(fā)者
    "Audience": "XiaoWang", // 接收者
    "Expired": 30 // 過期時間(30min)
  }

.net8 jwt,C#,asp.net,學(xué)習(xí),后端

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

     /// <summary>
     /// 發(fā)布者
     /// </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,學(xué)習(xí),后端
.net8 jwt,C#,asp.net,學(xué)習(xí),后端

新建JwtHelper類

 public class JwtHelper
 {

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

     }

     /// <summary>
     /// 添加Jwt服務(wù)
     /// </summary>
     public void AddJwtService()
     {

     }

     /// <summary>
     /// 返回
     /// </summary>
     /// <returns></returns>
     public string GetJwtToken()
     {
         //簡單測試一下
         var token = JsonConvert.SerializeObject(JwtConfig);
         return token;
     }


 }

我們應(yīng)該使用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,學(xué)習(xí),后端

然后在控制器里面獲取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,學(xué)習(xí),后端
接下來我們修改一下GetJwtToken這個函數(shù)即可

完善JwtConfig

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

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

        /// <summary>
        /// 發(fā)布者
        /// </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,學(xué)習(xí),后端
.net8 jwt,C#,asp.net,學(xué)習(xí),后端
返回成功!

.net8 jwt,C#,asp.net,學(xué)習(xí),后端

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE3MTAzODUyODgsImV4cCI6MTcxMDM4NzA4OCwiaXNzIjoiWGlhb1dhbmciLCJhdWQiOiJYaWFvV2FuZyJ9.v7UbQOba7VoNgoiRsoIQkFJKQTFBMLJlYEKBIfdFV4o

授權(quán)

加密了,肯定要有對應(yīng)的授權(quán)

在JwtConfig里面添加對應(yīng)的授權(quán)

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

    /// <summary>
    /// 發(fā)布者
    /// </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>
    /// 認(rèn)證用的密鑰
    /// </summary>
    public SymmetricSecurityKey SymmetricSecurityKey => new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey));
}

.net8 jwt,C#,asp.net,學(xué)習(xí),后端

在JwtHelper中

/// <summary>
/// 添加Jwt服務(wù)
/// </summary>
public void AddJwtService(IServiceCollection services)
{
    services.AddAuthentication(option =>
    {
        //認(rèn)證middleware配置
        option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            //Token頒發(fā)機(jī)構(gòu)
            ValidIssuer = JwtConfig.Issuer,
            //頒發(fā)給誰
            ValidAudience = JwtConfig.Audience,
            //這里的key要進(jìn)行加密
            IssuerSigningKey = JwtConfig.SymmetricSecurityKey,
            //是否驗證Token有效期,使用當(dāng)前時間與Token的Claims中的NotBefore和Expires對比
            ValidateLifetime = true,
        };
    });
}

調(diào)用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();//要在授權(quán)之前認(rèn)證,這個和[Authorize]特性有關(guān)
            app.UseAuthorization();

一定要在za之前使用ca
.net8 jwt,C#,asp.net,學(xué)習(xí),后端

授權(quán)測試

我們接口最好單獨開一個獲取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認(rèn)證。想放開Jtw認(rèn)證,使用[AllowAnonymous]標(biāo)記方法即可

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");
        }
    }
}

認(rèn)證失敗的結(jié)果

.net8 jwt,C#,asp.net,學(xué)習(xí),后端

能通過Jwt的請求

既然我們攔截了請求,我們也得對符合規(guī)范的請求放行。那什么樣的請求能放行呢?在Header中的【Authorization】中添加【Bearer {token}】才能放行。

PostMan測試

.net8 jwt,C#,asp.net,學(xué)習(xí),后端
.net8 jwt,C#,asp.net,學(xué)習(xí),后端

測試成功!
.net8 jwt,C#,asp.net,學(xué)習(xí),后端

過期測試

.NetCore JWT token過期時間設(shè)置

Jwt的過期是由兩個數(shù)據(jù)綜合相加的。一個是生成Token的過期時間

.net8 jwt,C#,asp.net,學(xué)習(xí),后端
一個是緩沖時間,默認(rèn)5分鐘。因為服務(wù)器的時間可能不同步。

.net8 jwt,C#,asp.net,學(xué)習(xí),后端
所以總過期時間=過期時間+緩沖時間

.net8 jwt,C#,asp.net,學(xué)習(xí),后端
為了更簡單的獲取Token,我們直接把返回的Token自帶[Bearer ]這個前綴好了

Swagger 全局Header

在JwtHelper中添加全局靜態(tài)方法

/// <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授權(quán)(數(shù)據(jù)將在請求頭中進(jìn)行傳輸) 在下方輸入Bearer {token} 即可,注意兩者之間有空格",
        Name = "Authorization",//jwt默認(rèn)的參數(shù)名稱
        In = ParameterLocation.Header,//jwt默認(rèn)存放Authorization信息的位置(請求頭中)
        Type = SecuritySchemeType.ApiKey,
        BearerFormat = "JWT",
        Scheme = "Bearer"
    });
}

.net8 jwt,C#,asp.net,學(xué)習(xí),后端
.net8 jwt,C#,asp.net,學(xué)習(xí),后端
.net8 jwt,C#,asp.net,學(xué)習(xí),后端
.net8 jwt,C#,asp.net,學(xué)習(xí),后端
.net8 jwt,C#,asp.net,學(xué)習(xí),后端

獲取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;
 }

解密能拿到是因為我們加密的時候就已經(jīng)放進(jìn)去了

 /// <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()
 {
 	//我們加密的時候,就放進(jìn)去了一些額外的信息
     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,學(xué)習(xí),后端
這樣我們就可以把一些比較隱私的數(shù)據(jù)放在里面,比如用戶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服務(wù)
        /// </summary>
        public void AddJwtService(IServiceCollection services)
        {
            services.AddAuthentication(option =>
            {
                //認(rèn)證middleware配置
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    //Token頒發(fā)機(jī)構(gòu)
                    ValidIssuer = JwtConfig.Issuer,
                    //頒發(fā)給誰
                    ValidAudience = JwtConfig.Audience,
                    //這里的key要進(jìn)行加密
                    IssuerSigningKey = JwtConfig.SymmetricSecurityKey,
                    //是否驗證Token有效期,使用當(dāng)前時間與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授權(quán)(數(shù)據(jù)將在請求頭中進(jìn)行傳輸) 在下方輸入Bearer {token} 即可,注意兩者之間有空格",
                Name = "Authorization",//jwt默認(rèn)的參數(shù)名稱
                In = ParameterLocation.Header,//jwt默認(rèn)存放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測試成功!");
}

運行得到結(jié)果
.net8 jwt,C#,asp.net,學(xué)習(xí),后端

Jwt授權(quán)模式基礎(chǔ)講解

介紹三種授權(quán)方式(Policy、Role、Scheme),Scheme這種用的太少了,我們就簡單講解一下Policy和Role這兩種方式。Policy和Role的核心就在于我們封裝Token的時候添加的Claim對象。大家看到這里就會發(fā)現(xiàn),其實Jwt的核心就是裝包和拆包。網(wǎng)頁請求Token的時候拿到了個包裹,網(wǎng)頁發(fā)送Http的時候解開這個包裹。

我寫了一會,感覺有點累了。這里有個別人寫好的代碼,有興趣的自己去看吧。

ASP.NET Core 6.0 添加 JWT 認(rèn)證和授權(quán)

簡單的【角色授權(quán)】

獲取不同權(quán)限的Token

獲取不同權(quán)限的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);
}
不同權(quán)限的jwt認(rèn)證
/// <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枚舉類型,這樣不會出現(xiàn)拼寫錯誤

封裝好的代碼

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

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

        /// <summary>
        /// 發(fā)布者
        /// </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>
        /// 認(rèn)證用的密鑰
        /// </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服務(wù)
        /// </summary>
        public void AddJwtService(IServiceCollection services)
        {
            services.AddAuthentication(option =>
            {
                //認(rèn)證middleware配置
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    //Token頒發(fā)機(jī)構(gòu)
                    ValidIssuer = JwtConfig.Issuer,
                    //頒發(fā)給誰
                    ValidAudience = JwtConfig.Audience,
                    //這里的key要進(jìn)行加密
                    IssuerSigningKey = JwtConfig.SymmetricSecurityKey,
                    //是否驗證Token有效期,使用當(dāng)前時間與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授權(quán)(數(shù)據(jù)將在請求頭中進(jìn)行傳輸) 在下方輸入Bearer {token} 即可,注意兩者之間有空格",
                Name = "Authorization",//jwt默認(rèn)的參數(shù)名稱
                In = ParameterLocation.Header,//jwt默認(rèn)存放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();//要在授權(quán)之前認(rèn)證,這個和[Authorize]特性有關(guān)
            app.UseAuthorization();


            app.MapControllers();

            app.Run();
        }

        /// <summary>
        /// 為了防止代碼過于臃腫,將新的配置放在這里寫
        /// </summary>
        /// <param name="builder"></param>
        public static void AddMyService(WebApplicationBuilder builder)
        {
            #region 默認(rèn)的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標(biāo)題",
                    Description = $"API描述,v1版本"
                });
                var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                //IncludeXmlComments 第二參數(shù) true 則顯示 控制器 注釋
                options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename), true);
                JwtHelper.SwaggerAddJwtHeader(options);
            });
            #endregion 

            #region 添加Jwt服務(wù)
            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)
  }

總結(jié)

Jwt其實也不是特別難,就是第一次配置的時候容易被繞暈。Jwt的策略我暫時先跳過了,對于解決普通問題一般來說已經(jīng)夠用了。文章來源地址http://www.zghlxwxcb.cn/news/detail-844995.html

到了這里,關(guān)于ASP.NET Core 8.0 WebApi 從零開始學(xué)習(xí)JWT登錄認(rèn)證的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • ASP.NET Core SingleR Core:WebApi + .net 客戶端開發(fā)

    ASP.NET Core SingleR Core:WebApi + .net 客戶端開發(fā)

    我之前稍微研究了一下SignalR Core。用起來還行。簡單來說SignalR就是用來解決實時通訊的問題的。 ASP.NET Core SingleR:初次體驗和簡單項目搭建 SignalR支持三種客戶端,C#,Java,JavaScirpt?;緣蛴昧?。本身就是微軟開發(fā)的,肯定支持自己的語言。因為是Websocket的上層封裝,所以也要支

    2024年01月20日
    瀏覽(575)
  • Asp.net core Webapi 如何執(zhí)行定時任務(wù)?

    Asp.net core Webapi 如何執(zhí)行定時任務(wù)?

    在計算機(jī)系統(tǒng)中,定時執(zhí)行一些后臺任務(wù)是很常見的場景,比如定時發(fā)送郵件、備份數(shù)據(jù)等等。 那么,.NET 技術(shù)如何通過編程靈活地實現(xiàn)項目里復(fù)雜的自定義任務(wù)呢? 如果是 Windows 生態(tài),通常來說,可以有這些方式: 編寫一個程序,通過 Windows 內(nèi)置的任務(wù)計劃來定時執(zhí)行。

    2024年02月04日
    瀏覽(90)
  • .net 溫故知新【14】:Asp.Net Core WebAPI  緩存

    .net 溫故知新【14】:Asp.Net Core WebAPI 緩存

    緩存指在中間層中存儲數(shù)據(jù)的行為,該行為可使后續(xù)數(shù)據(jù)檢索更快。 從概念上講,緩存是一種性能優(yōu)化策略和設(shè)計考慮因素。 緩存可以顯著提高應(yīng)用性能,方法是提高不常更改(或檢索成本高)的數(shù)據(jù)的就緒性。 在最新的緩存控制規(guī)范文件RFC9111中,詳細(xì)描述了瀏覽器緩存和

    2024年02月05日
    瀏覽(91)
  • ASP.NET core WebApi Cors跨域解決

    ASP.NET core WebApi Cors跨域解決

    我用了最新版的Asp.net webapi ,在csdn上面搜跨域如何解決的時候,發(fā)現(xiàn)csdn上面對于.NET技術(shù)討論不是很多。沒辦法,只能面向官方文檔和GitHub編程了。 前面兩個已經(jīng)放棄維護(hù)了,我們就不用了。用最新的webApi 我們引入了最新的api后可以在官方網(wǎng)址上查看文檔(有些地址是gitH

    2024年04月29日
    瀏覽(96)
  • asp.net core webapi如何執(zhí)行周期性任務(wù)

    asp.net core webapi如何執(zhí)行周期性任務(wù)

    新建asp.net core webapi項目,使用Nuget搜索安裝Quartz包。 注意:定時執(zhí)行時間格式,參考連接:https://www.cnblogs.com/wudequn/p/8506938.html 在IIS中找到這個站點所用的程序池,點擊“高級設(shè)置…” 在打開的列表中更改以下設(shè)置: 回收——固定時間間隔(分鐘) 改為 0 ——虛擬/專用內(nèi)存

    2024年02月13日
    瀏覽(104)
  • .net 溫故知新【17】:Asp.Net Core WebAPI  中間件

    .net 溫故知新【17】:Asp.Net Core WebAPI 中間件

    到這篇文章為止,關(guān)于.NET \\\"溫故知新\\\"系列的基礎(chǔ)知識就完結(jié)了,從這一系列的系統(tǒng)回顧和再學(xué)習(xí),對于.NET core、ASP.NET CORE又有了一個新的認(rèn)識。 不光是從使用,還包括這些知識點的原理,雖然深入原理談不上,但對于日常使用也夠了,我想的是知其然,知其所以然。 在實際

    2024年01月18日
    瀏覽(96)
  • .net 溫故知新【11】:Asp.Net Core WebAPI 入門使用及介紹

    .net 溫故知新【11】:Asp.Net Core WebAPI 入門使用及介紹

    在Asp.Net Core 上面由于現(xiàn)在前后端分離已經(jīng)是趨勢,所以asp.net core MVC用的沒有那么多,主要以WebApi作為學(xué)習(xí)目標(biāo)。 我使用的是VS2022, .Net 7版本。 在創(chuàng)建界面有幾項配置: 配置Https 啟用Docker 使用控制器 啟用OpenAPI支持 不使用頂級語句 其中配置Https 是WebApi是否使用https協(xié)議,啟

    2024年02月07日
    瀏覽(90)
  • ASP.NET Core MVC 使用 JWT 的示例

    創(chuàng)建一個 ASP.NET Core MVC 項目。 添加 NuGet 包: Microsoft.AspNetCore.Authentication.JwtBearer:用于支持 JWT 的身份驗證。 System.IdentityModel.Tokens.Jwt:用于生成和驗證 JWT。 在 Startup.cs 文件中做如下修改: 請注意,在上述代碼中,您需要將以下參數(shù)替換為實際的值: \\\"your_issuer\\\" :發(fā)行者的標(biāo)

    2024年02月13日
    瀏覽(25)
  • ASP.NET Core WebAPI如何獲得遠(yuǎn)程文件返回文件流給前端?

    ASP.NET Core WebAPI如何獲得遠(yuǎn)程文件返回文件流給前端?

    ? 項目采用的是前后端分離的模式,后端使用ASP.NET Core WebAPI方式,將文件流返回給前端。 ? 前端采用的是Vue技術(shù)棧,采用的是axios調(diào)用后端接口。前端無法獲得fileName需要修改后端ASP.NET Core WebAPI項目中的【Startup.cs】文件。 ?修改ConfigureServices方法中的AddCors。 ? 代碼示例:

    2024年02月15日
    瀏覽(84)
  • 前后端分離,Asp.net core webapi 簡單 2 步,輕松配置跨域

    前后端分離,Asp.net core webapi 簡單 2 步,輕松配置跨域

    可以說,前后端分離已經(jīng)成為當(dāng)今信息系統(tǒng)項目開發(fā)的主流軟件架構(gòu)模式,微服務(wù)的出現(xiàn),讓前后端分離發(fā)展更是迅速,大量優(yōu)秀的前端框架如 vue.js、react 的出現(xiàn),也讓前后端分離趨勢加快。 所謂的前后端分離軟件架構(gòu)模式,就是指將前端和后端的開發(fā)完全分離,后端負(fù)責(zé)

    2024年01月17日
    瀏覽(16)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包