.Net Core 微服务实战 - 网关与BFF

源码及系列文章目录

Git 源码https://github.com/tangsong1995/TS.Microservices
CSDN 资源https://download.csdn.net/download/qq_33649351/34675095

系列文章目录https://blog.csdn.net/qq_33649351/article/details/120998558

什么是 BFF

BFF,即 Backend For Frontend(服务于前端的后端),也就是服务器设计 API 时会考虑前端的使用,并在服务端直接进行业务逻辑的处理。主要是负责服务聚合,便于前端使用。

网关

网关架构类型

直连模式:

在直连模式下,客户端直接连接微服务,类似于面向服务架构。

共享网关模式:
在这里插入图片描述
客户端通过网关来调用微服务,统一入口。

共享网关+聚合服务模式:
在这里插入图片描述
聚合服务负责跨服务件的数据组装。

专用网关模式:
在这里插入图片描述
在专用网关模式下,为每个客户端提供专用的网关;并且能够根据不同的客户端业务提供对应的接口,便于分类管理、故障隔离等。

基于 Ocelot 打造网关

首先需要 nuget 添加 Ocelot 包:
在这里插入图片描述
配置路由策略:

  "Routes": [
    {
      "DownstreamPathTemplate": "/api/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 5004
        }
      ],
      "UpstreamPathTemplate": "/mobileAgg/api/{everything}",
      "UpstreamHttpMethod": []
    },
    {
      "DownstreamPathTemplate": "/api/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 5000
        }
      ],
      "UpstreamPathTemplate": "/mobile/api/{everything}",
      "UpstreamHttpMethod": []
    }
  ]

以上规则的作用是将 /mobileAgg/api 路由至 http://localhost:5004 ,将 /mobile/api 路由至 http://localhost:5000 。
配置还有很多属性,例如:

  • Priority :定义匹配的顺序,数值越大,优先级越高
  • RouteIsCaseSensitive:路由匹配区分大小写,为 true 时区分,默认 false 不区分
  • … …

注册 Ocelot :

services.AddOcelot(Configuration);

在 Startup 的 Configure 方法中最后添加:

app.UseOcelot().Wait();

到此 Ocelot 就配置完成了,让我们来测试一下。

添加测试代码:

namespace TS.Microservices.WebApi.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        [HttpGet]
        public IActionResult TestOcelot()
        {
            return Content("TestOcelot TS.Microservices.WebApi");
        }
    }
}
namespace TS.Microservices.Mobile.ApiAggregator.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        [HttpGet]
        public IActionResult TestOcelot()
        {
            return Content("TestOcelot TS.Microservices.Mobile.ApiAggregator");
        }
    }
}
namespace TS.Microservices.Mobile.Gateway.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        [HttpGet]
        public IActionResult TestOcelot()
        {
            return Content("TestOcelot TS.Microservices.Mobile.Gateway");
        }
    }
}

启动项目并分别请求以下 URL ,可以看到 Ocelot 配置生效:
https://localhost:5003/api/test/TestOcelot
在这里插入图片描述
https://localhost:5003/mobileAgg/api/test/TestOcelot
在这里插入图片描述
https://localhost:5003/mobile/api/test/TestOcelot
在这里插入图片描述

JWT

JWT:JSON Web Tokens,是一种无状态 JSON 格式网络令牌。

JWT 数据结构

在这里插入图片描述

  • Header,令牌类型、加密类型等信息
  • Payload,表示令牌内容,预定义了部分字段信息,支持自定义
  • Signature,根据 Header、Payload 和 私有密钥计算出来的签名

使用 JWT 实现身份认证与授权

添加包:Microsoft.AspNetCore.Authentication.JwtBearer

配置身份认证:

public void ConfigureServices(IServiceCollection services)
{
    var secrityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SecurityKey"]));
    services.AddSingleton(secrityKey);
    services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,//是否验证Issuer
                ValidateAudience = true,//是否验证Audience
                ValidateLifetime = true,//是否验证失效时间
                ClockSkew = TimeSpan.FromSeconds(30),//失效时间的偏离时间,在失败后的指定时间内有效
                ValidateIssuerSigningKey = true,//是否验证SecurityKey
                ValidAudience = "localhost",//Audience
                ValidIssuer = "localhost",//Issuer
                IssuerSigningKey = secrityKey//拿到SecurityKey
            };
        });
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

    app.UseOcelot().Wait();
}

添加 Account 控制器:

[ApiController]
[Route("account/[action]")]
public class AccountController : Controller
{
    public async Task<string> Login()
    {
        return await Task.FromResult("请先登录");
    }

    public async Task<IActionResult> JwtLogin([FromServices] SymmetricSecurityKey securityKey, string userName)
    {

        List<Claim> claims = new List<Claim>();
        claims.Add(new Claim("Name", userName));
        var creds = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
        var token = new JwtSecurityToken(
            issuer: "localhost",
            audience: "localhost",
            claims: claims,
            expires: DateTime.Now.AddMinutes(30),
            signingCredentials: creds);
        var t = new JwtSecurityTokenHandler().WriteToken(token);
        return Content(t);
    }
}

使用 [Authorize] 标签注明接口需要认证:


[HttpGet]
[Authorize]
public IActionResult TestJwt()
{
    return Content(User.FindFirst("Name").Value);
}

[HttpGet]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public IActionResult TestJwt1()
{
    return Content(User.FindFirst("Name").Value);
}

注意事项

  • Payload 信息不宜过大
  • Payload 不宜存储敏感信息
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值