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();
                }
            }
        }
    }
}
相关推荐
勇往直前plus2 小时前
Sentinel微服务保护
java·spring boot·微服务·sentinel
只因在人海中多看了你一眼13 小时前
B.50.10.10-微服务与电商应用
微服务·云原生·架构
海上生明月丿20 小时前
微服务01
java·spring boot·微服务
野生技术架构师20 小时前
开发微服务的9个最佳实践
微服务·云原生·架构
叫我阿柒啊21 小时前
从Java全栈到前端框架的全面实战:一次真实面试的深度解析
java·spring boot·缓存·微服务·消息队列·vue3·rest api
喵叔哟21 小时前
54.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--新增功能--实现手机邮箱注册
微服务·智能手机·.net
方圆想当图灵1 天前
《生产微服务》评估清单 CheckList
后端·微服务
叫我阿柒啊1 天前
从Java全栈到Vue3实战:一次真实面试中的技术探索
java·数据库·spring boot·微服务·typescript·vue3·restful
喵叔哟1 天前
52.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--解决客户端调用接口404问题
微服务·架构·.net