You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咨询Ocelot是否支持Cookie Authentication及API网关实现方案

Ocelot是否支持Cookie Authentication?如何搭建处理Cookie认证的API网关?

问题解答

Ocelot完全支持Cookie Authentication,只是多数资料更侧重令牌类认证(如JWT),导致新手容易忽略这部分能力。以下是具体实现步骤:


1. 配置Cookie认证服务

在网关项目的Program.cs中,先添加Cookie认证服务和授权服务:

using Microsoft.AspNetCore.Authentication.Cookies;

var builder = WebApplication.CreateBuilder(args);

// 添加Cookie认证
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.LoginPath = "/Account/Login"; // 未认证时跳转的登录接口
        options.LogoutPath = "/Account/Logout";
        options.ExpireTimeSpan = TimeSpan.FromHours(2); // Cookie有效期
        options.SlidingExpiration = true; // 活动时自动延长有效期
        // 跨域场景下可配置Domain属性,如options.Cookie.Domain = ".yourdomain.com";
    });

// 添加授权服务
builder.Services.AddAuthorization();

// 添加Ocelot服务
builder.Services.AddOcelot(builder.Configuration);

var app = builder.Build();

// 中间件顺序很重要:认证、授权必须在Ocelot之前
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

// 启用Ocelot
await app.UseOcelot();

app.Run();

2. 配置Ocelot路由规则

在ocelot.json中,为需要认证的微服务路由添加AuthenticationOptions,指定Cookie认证的ProviderKey:

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/service1/{everything}",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "service1.yourdomain.com",
          "Port": 443
        }
      ],
      "UpstreamPathTemplate": "/service1/{everything}",
      "UpstreamHttpMethod": ["Get", "Post"],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "Cookies" // 对应Cookie认证的Scheme
      },
      "AuthorizationOptions": {
        "AllowedRoles": ["Admin", "User"] // 可选:限制访问角色
      }
    },
    // 微服务2、3的路由配置类似
    {
      "DownstreamPathTemplate": "/api/service2/{everything}",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "service2.yourdomain.com",
          "Port": 443
        }
      ],
      "UpstreamPathTemplate": "/service2/{everything}",
      "UpstreamHttpMethod": ["Get"],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "Cookies"
      }
    },
    {
      "DownstreamPathTemplate": "/api/service3/{everything}",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "service3.yourdomain.com",
          "Port": 443
        }
      ],
      "UpstreamPathTemplate": "/service3/{everything}",
      "UpstreamHttpMethod": ["Post"],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "Cookies"
      }
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "https://gateway.yourdomain.com"
  }
}

3. 实现登录/登出逻辑(网关侧)

如果网关负责统一登录,编写登录接口验证用户后颁发Cookie:

[ApiController]
[Route("Account")]
public class AccountController : ControllerBase
{
    [HttpPost("Login")]
    public async Task<IActionResult> Login([FromBody] LoginRequest request)
    {
        // 替换为实际的用户验证逻辑(如查询数据库)
        if (request.Username == "demo" && request.Password == "demo123")
        {
            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, request.Username),
                new Claim(ClaimTypes.Role, "User")
            };

            var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
            var authProps = new AuthenticationProperties
            {
                ExpiresUtc = DateTimeOffset.UtcNow.AddHours(2),
                IsPersistent = request.RememberMe
            };

            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), authProps);
            return Ok("登录成功");
        }

        return Unauthorized("用户名或密码错误");
    }

    [HttpPost("Logout")]
    public async Task<IActionResult> Logout()
    {
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        return Ok("退出登录成功");
    }
}

public class LoginRequest
{
    public string Username { get; set; }
    public string Password { get; set; }
    public bool RememberMe { get; set; }
}

注意事项

  • 若网关与微服务跨域名部署,需配置Cookie的Domain属性,确保Cookie能在域名间共享。
  • 微服务侧若需获取用户身份信息,可通过网关转发的HttpContext.User直接读取,无需重复认证。

内容的提问来源于stack exchange,提问作者Andrеw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:40:18