dotnet core微服务框架Jimu ~ 会员授权微服务

提供授权服务,用户使用会员的用户名和密码获取 token, 带着 token 访问受保护的接口,如浏览和发布新闻。

有 2 个公开的 api:

  1. token: 获取 token;
  2. GetCurrentMemberInfo: 获取当前 token 的会员信息;

有 1 个不公开的方法:

  1. GetMemberInfo:根据会员用户名和密码,获取会员信息,该方法供获取 token 的 api 调用;

1 声明接口,创建基于 .Net Core 6.0 的类库项目,命名为 Auth.IServices

1.1 添加 jimu 引用

复制代码
Install-Package  Jimu

1.2 创建 dto 类

复制代码
using System;
using System.Collections.Generic;
using System.Text;

namespace Auth.IServices
{
    public class MemberInfo
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string NickName { get; set; }
        public string Role { get; set; }

    }
}

1.3 声明公开的微服务接口

复制代码
using System;
using System.Collections.Generic;
using System.Text;
using Jimu;

namespace Auth.IServices
{
    public interface IAuthMemberService : IJimuService
    {
        MemberInfo GetMemberInfo(string username, string password);
    }
}

上面的接口只继承 IJimuService, 不声明访问路由和接口属性,因为它不公开给外部调用的,但要用 autofac 注册到系统,在生成 token 时调用,所以需要继承 IJimuService。

复制代码
using System;
using System.Threading.Tasks;
using Jimu;

namespace Auth.IServices
{
    [JimuServiceRoute("/api/v1/member")]
    public interface IMemberService : IJimuService
    {
        [JimuService(EnableAuthorization = true, CreatedBy = "grissom", CreatedDate = "2018-07-17", Comment = "get current token member info")]
        MemberInfo GetCurrentMemberInfo();
    }
}

上面的接口声明了 EnableAuthorization = true,需要授权的用户才能访问(即请求时要带上 token),该方法是获取当前会员信息。

2 实现接口,创建基于 .Net Core 6.0 的类库项目,命名为 Auth.Services

2.1 添加对接口项目 Auth.IServices 的引用

2.2 实现接口

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Auth.IServices;
using Jimu;

namespace Auth.Services
{
    public class AuthMemberService : IAuthMemberService
    {
        static List<MemberInfo> _membersDb = new List<MemberInfo>();
        readonly ILogger _logger;
        public AuthMemberService(ILogger logger)
        {
            _logger = logger;
        }

        static AuthMemberService()
        {
            // mock some member 
            _membersDb.Add(new MemberInfo { Id = Guid.NewGuid().ToString(), Name = "grissom", NickName = "Gil", Role = "admin" });
            _membersDb.Add(new MemberInfo { Id = Guid.NewGuid().ToString(), Name = "foo", NickName = "Fo", Role = "guest" });
        }

        public MemberInfo GetMemberInfo(string username, string password)
        {
            var member = _membersDb.FirstOrDefault(x => x.Name == username && "123" == password);

            _logger.Debug($"username: {username}, found {(member == null ? "no " : "")} member.");

            return member;
        }
    }
}

logger 是通过依赖注入的

复制代码
using Jimu;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Auth.IServices
{
    public class MemberService : IMemberService
    {
        readonly ILogger _logger;
        readonly JimuPayload _jimuPayload;
        public MemberService(ILogger logger, JimuPayload jimuPayload)
        {
            _logger = logger;
            _jimuPayload = jimuPayload;
        }

        public MemberInfo GetCurrentMemberInfo()
        {
            _logger.Debug($"current token member username: {_jimuPayload.Items["username"]}");

            return Newtonsoft.Json.JsonConvert.DeserializeObject<MemberInfo>(_jimuPayload.Items["member"].ToString());
        }


    }
}

logger 和 jimuPayload 都是通过依赖注入的。JimuPayload 是 Jimu 框架解析 token 获取的一些生成 token 时,添加的信息(参考下面生成 token 的方法)。如果请求的 token 无效,则 JimuPayload 为 null。

3 微服务的宿主服务器,创建基于 .Net Core 2.0 的控制台应用, 命名为 Auth.Server

3.1 添加对项目: Auth.Services 的引用

3.2 添加 jimu.server 和 Jimu.Common.Discovery.ConsulIntegration 引用

复制代码
Install-Package  Jimu.Server
Install-Package  Jimu.Common.Discovery.ConsulIntegration

3.3 启动 jimu 服务和生成 token 的代码

复制代码
using System;
using Autofac;
using Jimu;
using Jimu.Server;
using Jimu.Server.OAuth;
using Auth.IServices;

namespace Auth.Server
{
    class Program
    {
        static void Main(string[] args)
        {
            IServiceHost host = null;

            var builder = new ServiceHostServerBuilder(new ContainerBuilder())
             .UseLog4netLogger()
             .LoadServices("Auth.IServices", "Auth.Services")
             .UseDotNettyForTransfer("127.0.0.1", 8000)
             .UseConsulForDiscovery("127.0.0.1", 8500, "JimuService", $"127.0.0.1:8000")
             .UseJoseJwtForOAuth<DotNettyAddress>(new JwtAuthorizationOptions
             {
                 SecretKey = "123456", // 生成 token 的密钥
                 ExpireTimeSpan = new TimeSpan(3, 0, 0, 0), // token 有效时间 3 天
                 ValidateLifetime = true, // 是否启动验证 token 的有效时间
                 ServerIp = "127.0.0.1", // 生成 token 的宿主服务器地址
                 ServerPort = 8000, // 生成 token 的宿主服务器端口
                 TokenEndpointPath = "api/oauth/token?username=&password=", // 获取 token 的路由,注意后缀 ?username=&password= 是固定的
                 CheckCredential = new Action<JwtAuthorizationContext>(ctx =>
                 {
                     var memberService = host.Container.Resolve<IAuthMemberService>();

                     var member = memberService.GetMemberInfo(ctx.UserName, ctx.Password);
                     if (member == null)
                     {
                         ctx.Rejected("username or password is incorrect.", "");
                     }
                     else
                     {
                         // 上面提到的 JimuPayload 就是包含这些数据
                         ctx.AddClaim("roles", member.Role); // 添加角色到 token
                         ctx.AddClaim("member", Newtonsoft.Json.JsonConvert.SerializeObject(member)); // 把整个 member 序列化打包到 token

                     }
                 }), // 生成 token 的配置项和验证逻辑
             });
            using (host = builder.Build())
            {
                host.Run();
                while (true)
                {
                    Console.ReadKey();
                }
            }
        }
    }
}
相关推荐
Sam_Deep_Thinking14 小时前
连锁门店的外卖订单平台对接
java·微服务·架构·系统架构
@PHARAOH20 小时前
HOW - 构建一个轻量前后端一体服务
前端·微服务·服务端
白露与泡影21 小时前
轻量级微服务发布系统:Traefik + Nomad + Consul
微服务·架构·consul
DN金猿1 天前
SpringCloudAlibaba微服务启动报错
微服务·云原生·nacos·架构·springcloud·sca
无心水1 天前
【分布式利器:SOAF】蚂蚁开源的金融级微服务全家桶:SOFAStack 核心架构与实战选型对比
人工智能·分布式·微服务·金融·架构·开源·分布式利器
万里侯1 天前
云原生安全扫描:保护容器化应用的安全
微服务·容器·k8s
万里侯1 天前
GitOps实战:用Git管理基础设施
微服务·容器·k8s
逍遥德2 天前
SpringBoot自带TaskScheduler 接口使用详解:(02)微服务多实例模式下,爆发任务重复执行问题
spring boot·分布式·后端·微服务·中间件
weixin_408318042 天前
企业级直播平台技术选型与成本分析:三种方案架构对比
微服务·云原生·架构
万里侯2 天前
K8s和我:一人一狗的日常冒险
微服务·容器·k8s