• DDD实战进阶第一波(十):开发一般业务的大健康行业直销系统(实现经销商登录仓储与逻辑)


    上一篇文章主要讲了经销商注册的仓储和领域逻辑的实现,我们先把应用服务协调完成经销商注册这部分暂停一下,后面文章统一讲。

    这篇文章主要讲讲经销商登录的仓储和相关逻辑的实现。

    在现代应用程序前后端分离的实现中,通常不是将用户登录的信息存储在服务器端Session,因为会存在服务器Session无法传递的情况,也存在WebApi调用时

    无法通过Authorize Attribute判断用户是否已经登录并获取用户身份信息的问题。所以现代应用程序都是由服务器后端返回Token给客户端,客户端将Token存储在客户端

    Session中,客户端在请求后端接口时,带上Token,服务器端就能够识别客户端是否经过身份验证,而且可以直接拿到客户端的身份。

    要实现经销商的登录,主要由以下几个步骤组成。

    1.实现经销商登录时信息查询的仓储。

    2.在应用服务中,单独建立一个查询文件夹放置经销商登录的查询逻辑。

    3.在登录WebApi中,调用应用服务的查询逻辑并分发Token。

    1.实现经销商登录时信息查询的仓储:

     public interface ILoginRepository
        {
                Guid UserLogin(string tel, string password);
        }
     public class LoginEFCoreRepository : ILoginRepository
        {
            private readonly DbContext context;
            public LoginEFCoreRepository(DbContext context)
            {
                this.context = context;
            }
            public Guid UserLogin(string tel, string password)
            {
                var dealercontext = this.context as DealerEFCoreContext;
                var enpassword = MD5Encrption.GetMd5Str(password);
                var logindealer=
                    dealercontext.Login.Where(p => p.Code == tel && p.Password == enpassword).FirstOrDefault();
                if (logindealer != null)
                {
                    return logindealer.DealerId;
                }
                return Guid.Empty;
            }
    
              }

    2.应用服务中调用仓储完成用户登录的查询

    public class UserLoginQuery:BaseAppSrv
        {
            private readonly IRepository irepository;
            private readonly ILoginRepository iloginrepository;
            public UserLoginQuery(IRepository irepository, ILoginRepository iloginrepository)
            {
                this.iloginrepository = iloginrepository;
                this.irepository = irepository;
            }
            public Guid Login(UserLoginDTO userlogindto)
            {
                try
                {
                    using (irepository)
                    {
                        return iloginrepository.UserLogin(userlogindto.Telphone, userlogindto.Password);
                    }
                }
                catch(Exception error)
                {
                    throw error;
                }
            }
        }

    3.在登录WebApi中调用应用服务,并分发令牌

    [AllowAnonymous]
            [HttpPost]
            [Route("UserLogin")]
            public ResultEntity<UserLoginResultDTO> UserLogin([FromBody] UserLoginDTO userlogindto)
            {
                var result = new ResultEntity<UserLoginResultDTO>();
                var idealercontext = servicelocator.GetService<IDealerContext>();
                var irepository =
                    servicelocator.GetService<IRepository>(new ParameterOverrides { { "context", idealercontext } });
                var iloginrepository = servicelocator.GetService<ILoginRepository>(new ParameterOverrides { { "context", idealercontext } });
                UserLoginQuery userloginquery = new UserLoginQuery(irepository, iloginrepository);
                try
                {
                    var dealerid = userloginquery.Login(userlogindto);
                    if (dealerid != Guid.Empty)
                    {
                        var token = new JwtTokenBuilder()
                            .AddSecurityKey(JwtSecurityKey.Create("msshcjsecretmsshcjsecret"))
                            .AddSubject(userlogindto.Telphone)
                            .AddIssuer("DDD1ZXSystem")
                            .AddAudience("DDD1ZXSystem")
                            .AddClaim("role", "NormalUser")                        
                            .AddExpiry(600)
                            .Build();
    
                        var userloginresultdto = new UserLoginResultDTO();
                        userloginresultdto.Tel = userlogindto.Telphone;
                        userloginresultdto.DealerId = dealerid;
                        userloginresultdto.Token = token.Value;
    
                        result.IsSuccess = true;
                        result.Data = userloginresultdto;
                        result.Msg = "登录成功!";
                    }
                    else
                    {
                        result.ErrorCode = 300;
                        result.Msg = "登录失败!";
                    }
    
                }
                catch (Exception error)
                {
                    result.ErrorCode = 200;
                    result.Msg = error.Message;
                }
                return result;
            }

     这里的UserLoginDTO定义如下:

      public class UserLoginDTO
        {
            public string Telphone { get; set; }
            public string Password { get; set; }
        }

    这里的UserLoginResultDTO定义如下:

     public class UserLoginResultDTO
        {
            public string Tel { get; set; }
            public Guid DealerId { get; set; }
            public string Token { get; set; }
        }

    这里的JwtTokenBuilder定义如下:

    public class JwtTokenBuilder
        {
            private SecurityKey securityKey = null;
            private string subject = "";
            private string issuer = "";
            private string audience = "";
            private Dictionary<string, string> claims = new Dictionary<string, string>();
            private int expiryInMinutes = 5;
    
            public JwtTokenBuilder AddSecurityKey(SecurityKey securityKey)
            {
                this.securityKey = securityKey;
                return this;
            }
            public JwtTokenBuilder AddSubject(string subject)
            {
                this.subject = subject;
                return this;
            }
            public JwtTokenBuilder AddIssuer(string issuer)
            {
                this.issuer = issuer;
                return this;
            }
            public JwtTokenBuilder AddAudience(string audience)
            {
                this.audience = audience;
                return this;
            }
            public JwtTokenBuilder AddClaim(string type,string value)
            {
                this.claims.Add(type, value);
                return this;
            }
            public JwtTokenBuilder AddExpiry(int expiryInMinutes)
            {
                this.expiryInMinutes = expiryInMinutes;
                return this;
            }
    
            public JwtToken Build()
            {
                var claims = new List<Claim>
                {
                    new Claim(JwtRegisteredClaimNames.Sub,this.subject),
                    new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString())
    
                }.Union(this.claims.Select(item => new Claim(item.Key, item.Value)));
    
                var token = new JwtSecurityToken(issuer: this.issuer, audience: this.audience, claims: claims,
                    expires: DateTime.UtcNow.AddMinutes(this.expiryInMinutes), signingCredentials:
                    new SigningCredentials(this.securityKey, SecurityAlgorithms.HmacSha256));
                return new JwtToken(token);
            }
        }

    这里的BearerUserInfo定义如下:

    public class BearerUserInfo:Controller
        {
            public string GetUserName()
            {
                var principal = HttpContext.User as ClaimsPrincipal;
                if (principal != null)
                {
                    foreach(var claim in principal.Claims)
                    {
                        if (claim.Subject != null)
                        {
                            var subjectclaims = claim.Subject.Claims as List<Claim>;
                            return subjectclaims[0].Value;
                        }
                    }
                }
                return null;
            }
        }

    这里的JwtSecurityKey定义如下:

    public static class JwtSecurityKey
        {
            public static SymmetricSecurityKey Create(string secret)
            {
                return new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
            }
        }

    这里的JwtToken定义如下:

    public class JwtToken
        {
            private JwtSecurityToken token;
            public JwtToken(JwtSecurityToken token)
            {
                this.token = token;
            }
            public DateTime ValidTo => token.ValidTo;
            public string Value => new JwtSecurityTokenHandler().WriteToken(this.token);
        }

    以上采用了.net core中关于OWIN的使用,具体不清楚的属性和方法,可以参考OWIN中.net core的实现标准,这里就不累述了,具体可以参考微信公众号中的视频讲解。

    QQ讨论群:309287205

    DDD实战进阶视频请关注微信公众号:

     
  • 相关阅读:
    Android开发之SQLite的使用方法
    【转】如何分析解决Android ANR
    error log
    33层高楼为什么27楼和28楼最贵 次顶层房价高原因揭秘
    Could not allocate CursorWindow size due to error -12 错误解决方法
    过来人讲述买房血泪史:什么样的房子不能碰
    cocos2d-x删除vs2010项目模板
    Lua学习笔记5:类及继承的实现
    Linux vsftpd服务配置具体解释
    Android_Dialog_设置Dialog窗体的大小
  • 原文地址:https://www.cnblogs.com/malaoko/p/9035353.html
Copyright © 2020-2023  润新知