一、NuGet 包
注意:请根据实际 .NET 版本调整包兼容性,版本过大或过小可能导致 WebAPI 无法运行。
二、配置文件
1. appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Nacos": {
"ServerAddresses": [ "http://localhost:8848/" ],
"Namespace": "",
"UserName": "nacos",
"Password": "nacos",
"ContextPath": "/nacos",
"LogLevel": "Debug",
"RequestTimeout": 10000,
"ServiceName": "OcelotGateway"
}
}
2. ocelot.json
{
"Routes": [
{
"DownstreamPathTemplate": "/api/{catchAll}",
"UpstreamPathTemplate": "/api/{catchAll}",
"UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE" ],
"DownstreamScheme": "http",
"UseServiceDiscovery": true,
"ServiceName": "GuangDongData",
"NacosNamespace": "public",
"NacosGroupName": "DEFAULT_GROUP",
"GroupName": "DEFAULT_GROUP",
"AuthenticationOptions": {
"AuthenticationProviderKey": "CustomGuidToken"
3. Program.cs
using Auth.StaticVar;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.OpenApi;
using Nacos.V2;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Provider.Nacos;
var builder = WebApplication.CreateBuilder(args);
// 1. 加载 Ocelot 配置
builder.Configuration.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);
// 2. 加载 Nacos 配置
builder.Services.AddOcelot().AddNacosDiscovery();
// 3. 自定义鉴权
builder.Services.AddAuthentication("CustomGuidToken")
.AddScheme<AuthenticationSchemeOptions, CustomGuidTokenHandler>("CustomGuidToken", options => { });
builder.Services.AddControllers();
builder.Services.AddSwaggerGen(options => {
options.SwaggerDoc("v1", new() {
Title = "API",
Version = "v1",
Description = "文档示例"
});
});
var app = builder.Build();
PubliVar.IsDevelopment = app.Environment.IsDevelopment();
if (app.Environment.IsDevelopment()) {
app.UseSwagger();
app.UseSwaggerUI(options => {
options.SwaggerEndpoint("/swagger/v1/swagger.json", "你的 API v1");
options.RoutePrefix = string.Empty;
});
}
// 4. 认证
app.UseAuthentication();
app.UseAuthorization();
// 5. 启用 Ocelot 网关
await app.UseOcelot();
app.MapControllers();
app.Run();
三、鉴权认证代码
注意:生产环境建议从 Redis 读取 Token,此处仅为演示硬编码逻辑。
1. 基础代码
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
using Nacos;
using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Text.Json;
/// <summary>
/// 自定义认证处理器:校验请求头中的 token 是否等于写死的 GUID
/// </summary>
public class CustomGuidTokenHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
// 写死的 GUID Token
private const string FixedGuidToken = "f0e92635-5141-4ce2-9690-563ca18fdd3d";
public CustomGuidTokenHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock)
: base(options, logger, encoder, clock)
{
}
/// <summary>
/// 核心认证逻辑:校验 token
/// </summary>
protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
{
try
{
// 1. 从请求头获取 token
var authHeader = Request.Headers["Authorization"].FirstOrDefault();
// 无 token,认证失败
(.IsNullOrEmpty(authHeader))
{
Response.StatusCode = StatusCodes.Status401Unauthorized;
Response.ContentType = ;
error = JsonSerializer.Serialize( { code = , message = });
Response.WriteAsync(error);
AuthenticateResult.Fail();
}
token = authHeader.StartsWith() ? authHeader.Substring(.Length).Trim() : authHeader.Trim();
(token != FixedGuidToken)
{
Response.StatusCode = StatusCodes.Status401Unauthorized;
Response.ContentType = ;
error = JsonSerializer.Serialize( { code = , message = });
Response.WriteAsync(error);
AuthenticateResult.Fail();
}
claims = List<Claim> {
Claim(ClaimTypes.Name, ),
Claim(ClaimTypes.Role, )
};
identity = ClaimsIdentity(claims, Scheme.Name);
principal = ClaimsPrincipal(identity);
ticket = AuthenticationTicket(principal, Scheme.Name);
Context.Request.Headers[] = ;
Context.Request.Headers[] = ;
Task.FromResult(AuthenticateResult.Success(ticket));
}
(Exception ex)
{
Task.FromResult(AuthenticateResult.Fail());
}
}
}
2. 简单登录演示(简单鉴权)
建议:生产环境中应将鉴权服务独立注册至 Nacos,而非直接嵌入网关。
// 如果只是鉴权的,直接返回给客户端
if (Request.Path.ToString().StartsWith("/api/Auth"))
{
// 直接向客户端返回 200+ 自定义成功 JSON
Response.StatusCode = StatusCodes.Status200OK;
Response.ContentType = "application/json";
var success = JsonConvert.SerializeObject(new { code = 200, message = "Token 验证通过,登录成功!", isValid = true });
await Response.WriteAsync(success);
// 返回 Success 终止后续认证流程
return AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(), Scheme.Name));
}
四、后端获取用户相关信息
后端可直接读取请求头中的自定义用户信息。

