领域驱动设计DDD与微服务实战案例进阶

领域驱动设计实战进阶第一波(十):实现经销商登录仓储与逻辑

2018-05-15  本文已影响10人  malaoko

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

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

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

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

无法通过Authorize Attribute判断用户是否已经登录并获取用户身份信息的问题。所以现代应用程序都是由服务器后端返回Token给客户端,客户端将Token存储在客户端Session中,客户端在请求后端接口时,带上Token,服务器端就能够识别客户端是否经过身份验证,而且可以直接拿到客户端的身份。

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

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

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

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

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

publicinterface ILoginRepository

    {

            Guid UserLogin(stringtel,string password);

    }

publicclass LoginEFCoreRepository : ILoginRepository

    {

        privatereadonly DbContext context;

        public LoginEFCoreRepository(DbContext context)

        {

            this.context = context;

        }

        publicGuid UserLogin(stringtel,string password)

        {

            vardealercontext =this.contextas DealerEFCoreContext;

            varenpassword = MD5Encrption.GetMd5Str(password);

            varlogindealer=                dealercontext.Login.Where(p => p.Code == tel && p.Password == enpassword).FirstOrDefault();

            if(logindealer !=null)

            {

                return logindealer.DealerId;

            }

            return Guid.Empty;

        }

          }

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

publicclass UserLoginQuery:BaseAppSrv

    {

        privatereadonly IRepository irepository;

        privatereadonly 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")]

        publicResultEntity UserLogin([FromBody] UserLoginDTO userlogindto)

        {

            varresult =newResultEntity();

            varidealercontext = servicelocator.GetService();

            varirepository =                servicelocator.GetService(newParameterOverrides { {"context", idealercontext } });

            variloginrepository = servicelocator.GetService(newParameterOverrides { {"context", idealercontext } });

            UserLoginQuery userloginquery =new UserLoginQuery(irepository, iloginrepository);

            try            {

                vardealerid = userloginquery.Login(userlogindto);

                if(dealerid != Guid.Empty)

                {

                    vartoken =new JwtTokenBuilder()

                        .AddSecurityKey(JwtSecurityKey.Create("msshcjsecretmsshcjsecret"))

                        .AddSubject(userlogindto.Telphone)

                        .AddIssuer("DDD1ZXSystem")

                        .AddAudience("DDD1ZXSystem")

                        .AddClaim("role","NormalUser")                       

                        .AddExpiry(600)

                        .Build();

                    varuserloginresultdto =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定义如下:

publicclass UserLoginDTO

    {

        publicstringTelphone {get;set; }

        publicstringPassword {get;set; }

    }

这里的UserLoginResultDTO定义如下:

publicclass UserLoginResultDTO

    {

        publicstringTel {get;set; }

        publicGuid DealerId {get;set; }

        publicstringToken {get;set; }

    }

这里的JwtTokenBuilder定义如下:

publicclass JwtTokenBuilder

    {

        privateSecurityKey securityKey =null;

        privatestringsubject ="";

        privatestringissuer ="";

        privatestringaudience ="";

        privateDictionary claims =newDictionary();

        privateintexpiryInMinutes =5;

        public JwtTokenBuilder AddSecurityKey(SecurityKey securityKey)

        {

            this.securityKey = securityKey;

            returnthis;

        }

        publicJwtTokenBuilder AddSubject(string subject)

        {

            this.subject = subject;

            returnthis;

        }

        publicJwtTokenBuilder AddIssuer(string issuer)

        {

            this.issuer = issuer;

            returnthis;

        }

        publicJwtTokenBuilder AddAudience(string audience)

        {

            this.audience = audience;

            returnthis;

        }

        publicJwtTokenBuilder AddClaim(stringtype,string value)

        {

            this.claims.Add(type, value);

            returnthis;

        }

        publicJwtTokenBuilder AddExpiry(int expiryInMinutes)

        {

            this.expiryInMinutes = expiryInMinutes;

            returnthis;

        }

        public JwtToken Build()

        {

            varclaims =newList            {

                newClaim(JwtRegisteredClaimNames.Sub,this.subject),

                new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString())

            }.Union(this.claims.Select(item =>new Claim(item.Key, item.Value)));

            vartoken =newJwtSecurityToken(issuer:this.issuer, audience:this.audience, claims: claims,

                expires: DateTime.UtcNow.AddMinutes(this.expiryInMinutes), signingCredentials:

                newSigningCredentials(this.securityKey, SecurityAlgorithms.HmacSha256));

            returnnew JwtToken(token);

        }

    }

这里的BearerUserInfo定义如下:

publicclass BearerUserInfo:Controller

    {

        publicstring GetUserName()

        {

            varprincipal = HttpContext.Useras ClaimsPrincipal;

            if(principal !=null)

            {

                foreach(varclaimin principal.Claims)

                {

                    if(claim.Subject !=null)

                    {

                        varsubjectclaims = claim.Subject.ClaimsasList;

                        returnsubjectclaims[0].Value;

                    }

                }

            }

            returnnull;

        }

    }

这里的JwtSecurityKey定义如下:

publicstaticclass JwtSecurityKey

    {

        publicstaticSymmetricSecurityKey Create(string secret)

        {

            returnnew SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));

        }

    }

这里的JwtToken定义如下:

publicclass JwtToken

    {

        private JwtSecurityToken token;

        public JwtToken(JwtSecurityToken token)

        {

            this.token = token;

        }

        publicDateTime ValidTo => token.ValidTo;

        publicstringValue =>newJwtSecurityTokenHandler().WriteToken(this.token);

    }

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

QQ讨论群:309287205

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

上一篇 下一篇

猜你喜欢

热点阅读