前言
微软文档 刚开始上手Core 6,写博客记录一下。有不足之处请多指教。
一、创建第一个Core 6 项目
开发工具:Visual Studio 2022 Core版本:.Net Core 6
😁创建项目
Ⅰ.**创建新项目:**打开开发工具>创建新项目>搜索API>选择C#语言的ASP.NET Core Web API Ⅱ.**配置新项目:**自定义项目信息以及存储路径 Ⅲ.其他信息:这里框架必须选择.NET 6.0,其他配置默认勾选即可,也可以根据自己的需求进行更改。(如果没有安装6.0,请看下一步) Ⅳ.更改开发工具安装 ①打开开发工具,选择 继续但无需代码
②导航栏>工具>获取工具和功能 ③安装你需要的工具和功能
Ⅴ.创建完成之后就得到了一个最基础的Core6项目框架代码
😥Program.cs
Program.cs就是该项目程序的配置,在Core6中Program.cs 集成了 Startup.cs 的配置,详细的查看官网文档或者百度都行。因为我也是小白一枚请见谅🙏。 官网文档 迁移到 ASP.NET Core 6.0 中新的最小托管模型的代码示例
🤨创建Controller
可以先将系统默认创建的WeatherForecastController.cs和WeatherForecast.cs进行删除,然后在controller文件夹新建一个控制器,命名:UserController.cs
在UserController中增加一个Hello的get方式的接口方法,返回"你好世界",通过请求api/user/hello来获取该接口的结果
点击运行后,开发工具会自动编译后启动。 会生成一个exe文件并自动运行,运行成功后会打开浏览器进行查看
由于在创建项目时我们已经勾选了Swagger服务,所以启动后的项目会使用Swagger UI 进行展示。
点击User接口>Try it out 就可以得到该接口的返回值及一些相关的属性
🤔总结
其实项目的创建以及控制器的创建和 core3是一致,只是.Net Core 6 给我的感觉就是比以往的版本更精简。可以将Swagger在创建项目时直接生成,而不需要手动的去配置。
二、读取appsettings.json
参考文章一 参考文章二
使用Nuget安装 Microsoft.Extensions.Configuration Microsoft.Extensions.Configuration.Json Microsoft.Extensions.Configuration.Binder 根据自己的开发环境选择合适的版本进行安装
Ⅰ、新建Helper文件夹用来存放帮助类,并添加一个AppSettings.cs 这里
public class Appsettings
{
static IConfiguration? Configuration { get; set; }
static string? ContentPath { get; set; }
public Appsettings(string contentPath)
{
string Path = "appsettings.json";
Configuration = new ConfigurationBuilder()
.SetBasePath(contentPath)
.Add(new JsonConfigurationSource { Path = Path, Optional = false, ReloadOnChange = true })
.Build();
}
public Appsettings(IConfiguration configuration)
{
Configuration = configuration;
}
public static string App(params string[] sections)
{
try
{
if (sections.Any())
{
#pragma warning disable CS8602
return Configuration[string.Join(":", sections)];
#pragma warning restore CS8602
}
}
catch (Exception)
{
}
return "";
}
public static List<T> App<T>(params string[] sections)
{
List<T> list = new();
Configuration.Bind(string.Join(":", sections), list);
return list;
}
}
Ⅱ、修改Program.cs ①在 var builder = WebApplication.CreateBuilder(args); 前增加
IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
②在 var builder = WebApplication.CreateBuilder(args); 后增加
builder.Services.AddSingleton(new Appsettings(configuration));
③读取 appsettings.json 代码
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"AppSettings": {
"ConnectionString": "Server=127.0.0.1;User Id=用户id;Password=密码;Database=数据库名称;"
}
}
读取
var text = Appsettings.App(new string[] { "AppSettings", "ConnectionString" });
三、修改Program.cs
😀跨域
官方文档 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 在 ASP.NET Core 中启用跨源请求 (CORS) ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 官网文档给出了不同的跨域请求解决方案,可以根据实际需求进行选择自己喜欢的方案。 我这里就配置最简单的 具有默认策略和中间件的 CORS
在 var builder = WebApplication.CreateBuilder(args); 后面添加如下代码;在这里我并没有针对到具体的地址,而是使用 AllowAnyOrigin() 确保策略允许任何源 这里 policy后面的方法可以查看👉CorsPolicyBuilder 类
方法 | 属性 |
---|
AllowAnyHeader() | 确保策略允许任何标头 | AllowAnyMethod() | 确保策略允许任何方法 | AllowAnyOrigin() | 确保策略允许任何源 | AllowCredentials() | 设置策略以允许凭据 |
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(
policy =>
{
policy.AllowAnyOrigin().AllowAnyHeader();
});
});
注册中间件 ?中间件顺序 ASP.NET Core 中间件 注册中间件时,顺序最好按照官网给出的依次进行注册,不然会无法生效
UseCors 添加 CORS 中间件。 对 UseCors 的调用必须放在 UseRouting 之后,但在 UseAuthorization 之前。
app.UseRouting();
app.UseCors();
app.UseAuthorization();
完整代码
IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton(new Appsettings(configuration));
var text = Appsettings.App(new string[] { "AppSettings", "ConnectionString" });
Console.WriteLine($"ConnectionString:{text}");
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
});
});
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseCors();
app.UseAuthorization();
app.MapControllers();
app.Run();
😁修改启动的Url
虽然修改启动的Url的并不需要动Program.cs文件中的配置,为了方便查看我还是放到这里来进行叙述。
其实这个也没啥好说的,只是Core6版的配置和之前的有那么一丢丢不一样,俗话说好记性不如烂笔头。所以我还是在这记录下来啦。 其实在查看官网文档👉Kestrel 终结点配置 之后你就会觉得So easy
Kestrel 特定的终结点配置将覆盖所有跨服务器终结点配置 找到项目中的 appsettings.json 文件,在该Josn文件中加入以下代码
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://localhost:7521"
},
"Https": {
"Url": "https://localhost:7526"
}
}
},
这里的IP地址根据core3的配置方法,我猜测可以将IP地址换为*号,只是开发工具会发出警告,因为部署到服务器上我想让他自己匹配服务器的IP,而不是我在这进行编辑。因为我也还没部署到服务器上,先大胆假设一下吧,等到后面我部署到服务器上在回来完善这一部分。
然后在启动项目后,项目的请求地址就会发生改变 在这里还有一个问题哈,就是在创建的时候如果默认勾选了HTTS服务,那么在项目创建完成之后会在Program.cs 的中间件中默认注册 app.UseHttpsRedirection(); 。 在执行了上面修改启动URL的时候,如果此时加入了一个HTTP的URL,你会发现去请求这个HTTP下的接口服务时,它会告诉你请求不了,然而HTTS下的接口服务却正常。
原因:HTTPS 重定向中间件 (UseHttpsRedirection) 将 HTTP 请求重定向到 HTTPS。
这时候只需要将app.UseHttpsRedirection();注释或者删除即可
四、启用JWT鉴权
什么是 JSON Web 令牌? JSON Web Token (JWT) 是一种开放标准 (RFC 7519),它定义了一种紧凑且独立的方式,用于将信息作为 JSON 对象在各方之间安全地传输。此信息可以进行验证和信任,因为它是经过数字签名的。JWT 可以使用密钥(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对进行签名。 JWT官网 JWT详解
网上对JWT的讲解有很多,我就不在这过多叙述啦。
😺生成Token令牌
在项目中找到appsettings.json,在appsettings.json中配置jwt参数的值 【注意】 SecretKey必须大于16个,是大于,不是大于等于。
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"AppSettings": {
"ConnectionString": "Server=127.0.0.1;User Id=用户id;Password=密码;Database=数据库名称;",
"JwtSetting": {
"Issuer": "jwtIssuer",
"Audience": "jwtAudience",
"SecretKey": "chuangqianmingyueguang"
}
}
}
😸安装需要的包
- IdentityModel
- Microsoft.AspNetCore.Authentication.JwtBearer
- Microsoft.AspNetCore.Authorization
😹新建TokenModel类
该类是JWT的返回实体类,创建位置根据你的项目情况而定,注意刚刚安装的包的位置!!!
public class TokenModel
{
public string? Uid { get; set; }
public string? Role { get; set; }
}
😻新建JwtHelper.cs
注意建立的位置与刚刚安装的包的位置!!! 以下代码来自博客园
public class JwtHelper
{
public static string IssueJwt(TokenModel tokenModel)
{
string iss = Appsettings.App(new string[] { "AppSettings", "JwtSetting", "Issuer" });
string aud = Appsettings.App(new string[] { "AppSettings", "JwtSetting", "Audience" });
string secret = Appsettings.App(new string[] { "AppSettings", "JwtSetting", "SecretKey" });
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ToString()),
new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(1000)).ToUnixTimeSeconds()}"),
new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(1000).ToString()),
new Claim(JwtRegisteredClaimNames.Iss,iss),
new Claim(JwtRegisteredClaimNames.Aud,aud),
};
claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var jwt = new JwtSecurityToken(
issuer: iss,
claims: claims,
signingCredentials: creds);
var jwtHandler = new JwtSecurityTokenHandler();
var encodedJwt = jwtHandler.WriteToken(jwt);
return encodedJwt;
}
public static TokenModel SerializeJwt(string jwtStr)
{
var jwtHandler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
object role;
try
{
jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
var tm = new TokenModel
{
Uid = jwtToken.Id.ToString(),
Role = role != null ? role.ToString() : "",
};
return tm;
}
}
😼获取Token
UserController新建Login接口,用来获取token 注意一个控制器多个接口时[HttpGet(“Login”)]需要在方法后面加入接口名称
[HttpGet("Login")]
public IActionResult Login(string role)
{
string jwtStr = string.Empty;
bool suc = false;
if (role != null)
{
TokenModel tokenModel = new TokenModel { Uid = "abcde", Role = role };
jwtStr = JwtHelper.IssueJwt(tokenModel);
suc = true;
}
else
{
jwtStr = "login fail!!!";
}
return Ok(new
{
success = suc,
token = jwtStr
});
}
运行项目,请求Login接口输入参数即可获得Token值
😽Swagger中开启JWT服务
要测试 JWT 授权认证,就必定要输入 Token令牌,那怎么输入呢,平时的话,我们可以使用 Postman 来控制输入,就是在请求的时候,在 Header 中,添加Authorization属性。但是现在使用了 Swagger 作为接口文档,那怎么输入呢,其实 Swagger 已经帮我们实现了这个录入 Token令牌的功能。 在Program.cs文件中找到👉builder.Services.AddSwaggerGen();方法,将该方法改为以下所示 注意需要安装包 Swashbuckle.AspNetCore.Filters
builder.Services.AddSwaggerGen(options =>
{
options.OperationFilter<SecurityRequirementsOperationFilter>();
#region Token绑定到ConfigureServices
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey
});
#endregion
});
运行项目后在接口主页面右上方就能看到Token的入口。
🙀JWT授权认证
新建AuthorizationSetup.cs 代码来自博客园
public static class AuthorizationSetup
{
public static void AddAuthorizationSetup(this IServiceCollection services)
{
if (services == null) throw new ArgumentNullException(nameof(services));
var symmetricKeyAsBase64 = Appsettings.App(new string[] { "AppSettings", "JwtSetting", "SecretKey" });
var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
var signingKey = new SymmetricSecurityKey(keyByteArray);
var Issuer = Appsettings.App(new string[] { "AppSettings", "JwtSetting", "Issuer" });
var Audience = Appsettings.App(new string[] { "AppSettings", "JwtSetting", "Audience" });
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateIssuer = true,
ValidIssuer = Issuer,
ValidateAudience = true,
ValidAudience = Audience,
ValidateLifetime = true,
ClockSkew = TimeSpan.FromSeconds(30),
RequireExpirationTime = true,
};
services.AddAuthentication("Bearer")
.AddJwtBearer(o =>
{
o.TokenValidationParameters = tokenValidationParameters;
o.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Add("Token-Expired", "true");
}
return Task.CompletedTask;
}
};
});
}
}
在Program.cs中注册验证服务 官网文档👉ASP.NET Core 身份验证概述
builder.Services.AddAuthorizationSetup();
注册中间件 ASP.NET Core 中间件顺序
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
😿API接口授权策略
对接口进行授权的方式有两种:
直接对需要进行授权验证的接口 [Authorize] 加上这个配置信息 注意需要引入这个包Microsoft.AspNetCore.Authorization
[HttpGet("Hello")]
[Authorize]
public string Hello()
{
return "你好世界";
}
第二种则是对整个控制器加上 [Authorize] 标识那么该控制器对于的所有接口都需要进行授权才能进行访问。 使用 **[AllowAnonymous]**可以取消授权验证
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using webapi.core.model;
using Webapi.Core.Common.Helper;
namespace WebApplication1.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class UserController : ControllerBase
{
[HttpGet("Hello")]
public string Hello()
{
return "你好世界";
}
[HttpGet("Login")]
[AllowAnonymous]
public IActionResult Login(string role)
{
string jwtStr = string.Empty;
bool suc = false;
if (role != null)
{
TokenModel tokenModel = new TokenModel { Uid = "abcde", Role = role };
jwtStr = JwtHelper.IssueJwt(tokenModel);
suc = true;
}
else
{
jwtStr = "login fail!!!";
}
return Ok(new
{
success = suc,
token = jwtStr
});
}
}
}
😾 解析Token
主要是调用JwtHelper下的SerializeJwt方法
[HttpGet]
[Authorize]
public IActionResult ParseToken()
{
var tokenHeader = HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
var user = JwtHelper.SerializeJwt(tokenHeader);
return Ok(user);
}
在这里我在记录一下如何获取payload的信息,因为有时候需要获取里面的信息进行返回
#region 获取payload信息
var handler = new JwtSecurityTokenHandler();
var payload = handler.ReadJwtToken(jwtStr).Payload;
var claims = payload.Claims;
var expireTime = claims.First(claim => claim.Type == "exp").Value;
#endregion
基于角色进行接口的授权,请查看文章👉Net core 3 JWT授权方法都是一样的所以我就不过多阐述,有问题可以直接私我
参考链接
|