.NET Core 3.1 Startup类相关配置(注册跨域、Swagger服务、Jwt服务)
创建ASP.NET Core Web应用程序
创建过程中,我这里选的是.NET Core 3.1 API(没有勾选HTTPS配置)
- Startup类默认配置
一. 跨域配置
Startup类,在配置服务的 ConfigureServices(IServiceCollection services) 方法中注册跨域
// 注册跨域配置
services.AddCors(ky =>
{
ky.AddPolicy("cors", yx =>
{
yx.WithOrigins("http://*.*.*.*") // 指定的来源加入原则。
.AllowAnyHeader() // 允许任何标题
.AllowAnyMethod() // 运行任何方法
.AllowAnyOrigin();// 允许任何来源的主机访问
});
});
- 在 配置 Configure(IApplicationBuilder app, IWebHostEnvironment env)
方法中启用跨域服务
// 启用跨域服务
app.UseCors("cors");
二. 注册Swagger服务
1.安装NuGet包
- 注册Swagger服务之前,需安装相应的NuGet包 Swashbuckle.AspNetCoreI
直接在NuGet包管理器中搜索 swagger 来找到,点击安装即可
2.注册、启用服务
- 安装后,在配置服务中注册swagger
// 注册swagger生成器,定义一个或者多个Swagger文档
services.AddSwaggerGen(sw =>
{
sw.SwaggerDoc("v1", new OpenApiInfo { Title = "MES 系统 Api 接口", Version = "v1", Description = "基于 .NET Core 3.1 的Api" });
// 获取xml文件路径
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
var xmlPath = Path.Combine(basePath, "MyApi.xml");
// 加载xml文件(为Swagger JSON and UI 设置xml文档注释路径)
sw.IncludeXmlComments(xmlPath, true);
});
- 在配置中,启用swagger
// 启用swagger
app.UseSwagger();
// 启用swaggerUI
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "");
});
3.生成xml文件,及其他操作
- swagger服务注册和启用后,需要右击项目,点击属性,点击生成,勾选XML文档文件,图示
最后在项目中点击Properties,打开launchSettings.json文件,更改启动后的默认显示路径,如果不需要运行后默认显示swagger的界面,为空字符就行;需要显示其他页面,改成其他的路径即可
- 直接上图:
**
之后使用 IIS Express
启动项目,会自动进入Swagger界面,创建了控制器后会显示控制器中的API接口,可以直接在界面中调用接口。
**
- 来一张比较凌乱的图片:
三. 配置Jwt
1.安装相应 NuGet 包
包 | 版本及说明 |
---|---|
Microsoft.AspNetCore.Authentication.JwtBearer | 我的项目框架是 .NET Core 3.1,不能安装最新的版本,最高只能安装到3.1.10 |
Microsoft.IdentityModel.Tokens | 到目前为止,可以安装到最新版 6.8.0 |
System.IdentityModel.Tokens.Jwt | 到目前为止,可以安装到最新版 6.8.0 |
2.注册 Jwt 服务
- 配置服务中注册 Jwt 服务代码
#region 注册jwt相关服务
// 设置添加身份验证
services.AddAuthentication(options =>
{
//默认身份验证方案
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;// 承载身份验证使用的默认值
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
// 获取或设置用于验证标识标记的参数
options.TokenValidationParameters = new TokenValidationParameters
{
// 验证颁发者
ValidateIssuer = true,
// 验证访问者
ValidateAudience = true,
// 验证生存期
ValidateLifetime = true,
// 验证使用者的签名秘钥
ValidateIssuerSigningKey = true,
// 设置颁发者
ValidIssuer = "MyIssue",
// 设置访问者
ValidAudience = "MyAudience",
//在验证令牌生命周期时间到后,立即过期;默认的是300秒
//默认是300秒,也就是5分钟后,假如生命周期设置的是30秒,还需要加上这300秒
ClockSkew = TimeSpan.Zero,
//设置秘钥------返回令牌对称安全密钥的新实例
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("873D82D99180B30807F4DA6893369D88"))
};
// 身份验证处理过程的控制相关事件
options.Events = new JwtBearerEvents()
{
// 第一次收到协议消息时调用
OnMessageReceived = context =>
{
//从请求头中获取token
string token = context.Request.Headers["token"];
//token是否为空字符,null或者空白字符
if (!string.IsNullOrWhiteSpace(token))
{
context.Token = token;//这里拿到token后会自动验证
}
return Task.CompletedTask;
},
// 在将资询发送给回调者之前调用(权限验证失败后触发)
OnChallenge = context =>
{
// 终止.NET Core默认的返回类型和结果
context.HandleResponse();
// 自定义返回结果
var myResult = JsonConvert.SerializeObject(new { code = 401, msg = "抱歉,您无权访问!" });
// 自定义返回数据类型
context.Response.ContentType = "applic/json";
// 自定义返回状态码(默认为200)(我这里改成401)
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
//输出json数据结果
context.Response.WriteAsync(myResult);
return Task.FromResult(0);
},
};
});
#endregion
- 启用服务配置
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
// 此方法由运行时调用。使用此方法配置HTTP请求管道。
// 创建应用程序的请求处理管道
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
// 启用身份验证(我们只需要启用这个)
app.UseAuthentication();
// 启用授权(这个默认就存在Startup类中了)
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// 启用中间件服务生成Swagger作为JSON终结点
app.UseCors("cors");
// 启用中间件服务对swagger-ui,指定Swagger JSON终结点
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "");
});
}
3.生成token令牌
- 创建一个生成令牌的工具类
public class JwtHelper
{
/// <summary>
/// 创建令牌
/// </summary>
/// <param name="claims">指定参数</param>
/// <returns></returns>
public static string GenerateToken(Claim[] claims)
{
//创建一个加密秘钥(长度在16位以上)——需和Startup类中Jwt配置中设置的秘钥一样
var secret = "873D82D99180B30807F4DA6893369D88";
//把秘钥字符串转换成字节数组,创建新的安全键实例
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
//使用安全键实例创建一个关键的信息,用什么加密算法
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
//安全令牌指定参数
var token = new JwtSecurityToken(
"MyIssue",//发行者——需和Startup类中Jwt配置中设置的颁发者一样
"MyAudience",//访问者——需和Startup类中Jwt配置中设置的访问者一样
claims,
expires: DateTime.Now.AddDays(1),//令牌过期时间
signingCredentials: credentials);
//创建Json Web令牌,安全令牌变成一个小型的JWT序列化格式。
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
4.创建测试代码
- 新建一个 API 控制器,创建一个登陆方法,一个测试方法
[Route("api/[controller]/[action]")]
[ApiController]
//全局添加了验证标识后,某个方法不需要验证过滤,需要在当前方法上添加一个取消验证的标识 [AllowAnonymous]
//[Authorize]//添加验证标识,
public class DefaultController : ControllerBase
{
/// <summary>
/// 登录
/// </summary>
/// <param name="accountName">账户名</param>
/// <param name="accountPwd">账户密码</param>
/// <returns></returns>
[HttpPost]
//[AllowAnonymous] //取消验证,全局添加验证标识后,需要在登录时候添加一个取消验证的标识,不然无法登录。
public object loginAccount([FromForm]string accountName, [FromForm]string accountPwd)
{
try
{
var account = new {AccountName="admin",AccountPwd="123456" };
if (accountName.Equals(account.AccountName) && accountPwd.Equals(account.AccountPwd))
{
//声明 用于创建临牌的参数(自己想加些什么参数就什么)
Claim[] claims = new Claim[] {new Claim("accountName",accountName),new Claim("accountPwd",accountPwd) };
//调用 Jwthelper 类来创建令牌
var token = JwtHelper.GenerateToken(claims);
//返回令牌
return new {code=200,message="登录成功!",data=new { token,accountName} };
}
else
{
return new { code = 200, message = "账号或密码错误!" };
}
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 测试一下
/// </summary>
/// <returns></returns>
[HttpGet]
[Authorize]//添加验证标识
public object TestToken()
{
try
{
return new { code = 200, message = "成功!", data = new {accountName,accountPwd } };
}
catch (Exception ex)
{
throw ex;
}
}
}
- 测试验证token时候,打断点查看 HttpContext.User.Identity 来的更容易懂
5.开始测试
- 运行项目后,在swaggerUI界面测试登录
- 测试登录,返回token
- swaggerUI界面测试,带不了请求头,需要使用Postman来测试,
- 这是请求头中不带 account_token 参数的请求,会自动进入之前配置中,从而返回自定义的结果,
- 当前携带的 token 参数不正确的话,也会如此
- - 携带正确的token
- -
其他
1.设置 API 可自动的动态接收参数
NuGet 包 | 说明 |
---|---|
Microsoft.AspNetCore.Mvc.NewtonsoftJson | 本项目是 .NET Core 3.1版本,最高只能安装3.1.10 |
- 在Startup类配置服务中注册
services.AddControllers().AddNewtonsoftJson();//api可以接受动态参数
- 登录代码
/// <summary>
/// 登录
/// </summary>
/// <param name="dy">通过解析操作对象,动态获取参数</param>
/// <returns></returns>
[HttpPost]
public object loginAccount(dynamic dy)
{
//获取账户名名称
string accountName = dy.accountName.ToString();
//获取账户密码
string accountPwd = dy.accountPwd.ToString();
try
{
var account = new { AccountName = "admin", AccountPwd = "123456" };
if (accountName.Equals(account.AccountName) && accountPwd.Equals(account.AccountPwd))
{
//声明 用于创建临牌的参数(自己想加些什么参数就什么)
Claim[] claims = new Claim[] { new Claim("accountName", accountName.ToString()), new Claim("accountPwd", accountPwd.ToString()) };
//调用 Jwthelper 类来创建令牌
string token = JwtHelper.GenerateToken(claims);
//返回令牌
return new { code = 200, message = "登录成功!", data = new { token, accountName } };
}
else
{
return new { code = 200, message = "账号或密码错误!" };
}
}
catch (Exception ex)
{
throw ex;
}
}
- 图示
完整的Startup配置代码
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// 此方法由运行时调用。使用此方法可将服务添加到容器中。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddControllers().AddNewtonsoftJson();//api可以接受动态参数
#region 跨域配置
// 注册跨域配置
services.AddCors(ky =>
{
ky.AddPolicy("cors", yx =>
{
yx.WithOrigins("http://*.*.*.*") // 指定的来源加入原则。
.AllowAnyHeader() // 允许任何标题
.AllowAnyMethod() // 运行任何方法
.AllowAnyOrigin();// 允许任何来源的主机访问
});
});
#endregion
#region Swagger服务
// 注册swagger生成器,定义一个或者多个Swagger文档
services.AddSwaggerGen(sw =>
{
sw.SwaggerDoc("v1", new OpenApiInfo { Title = "My Test Api 接口", Version = "v1", Description = "基于 .NET Core 3.1 的Api" });
// 加载xml文件(为Swagger JSON and UI 设置xml文档注释路径)
// 获取路径
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
var xmlPath = Path.Combine(basePath, "MyApi.xml");
sw.IncludeXmlComments(xmlPath, true);
});
#endregion
#region 注册jwt相关服务
// 设置添加身份验证
services.AddAuthentication(options =>
{
//默认身份验证方案
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;// 承载身份验证使用的默认值
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
// 获取或设置用于验证标识标记的参数
options.TokenValidationParameters = new TokenValidationParameters
{
// 验证颁发者
ValidateIssuer = true,
// 验证访问者
ValidateAudience = true,
// 验证生存期
ValidateLifetime = true,
// 验证使用者的签名秘钥
ValidateIssuerSigningKey = true,
// 设置颁发者
ValidIssuer = "MyIssuer",
// 设置访问者
ValidAudience = "MyAudience",
//设置秘钥------返回令牌对称安全密钥的新实例
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("873D82D99180B30807F4DA6893369D88"))
};
// 身份验证处理过程的控制相关事件
options.Events = new JwtBearerEvents()
{
// 第一次收到协议消息时调用
OnMessageReceived = context =>
{
//从请求头中获取token
string token = context.Request.Headers["token"];
//token是否为空字符,null或者空白字符
if (!string.IsNullOrWhiteSpace(token))
{
context.Token = token;//这里拿到token后会自动验证
}
return Task.CompletedTask;
},
// 在将资询发送给回调者之前调用(权限验证失败后触发)
OnChallenge = context =>
{
// 终止.NET Core默认的返回类型和结果
context.HandleResponse();
// 自定义返回结果
var myResult = JsonConvert.SerializeObject(new { code = 401, msg = "抱歉,您无权访问!" });
// 自定义返回数据类型
context.Response.ContentType = "applic/json";
// 自定义返回状态码(默认为200)(我这里改成401)
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
//输出json数据结果
context.Response.WriteAsync(myResult);
return Task.FromResult(0);
},
};
});
#endregion
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
// 此方法由运行时调用。使用此方法配置HTTP请求管道。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
//1.先开启认证
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseCors("cors");
// 启用服务
app.UseSwagger();
// 启用服务
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "");
});
}
}
结语
新手小白哈,有很多可能没注意到,写的不好,纯属当个人笔记,