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()
.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 = ;
result.Msg = "登录失败!";
} }
catch (Exception error)
{
result.ErrorCode = ;
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 = ; 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[].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实战进阶视频请关注微信公众号:
DDD实战进阶第一波(十):开发一般业务的大健康行业直销系统(实现经销商登录仓储与逻辑)的更多相关文章
- DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述)
本系列文章 DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述) DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一) 近年来,关于如何开发基于 ...
- DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一)
要实现软件设计.软件开发在一个统一的思想.统一的节奏下进行,就应该有一个轻量级的框架对开发过程与代码编写做一定的约束. 虽然DDD是一个软件开发的方法,而不是具体的技术或框架,但拥有一个轻量级的框架仍 ...
- DDD实战进阶第一波(八):开发一般业务的大健康行业直销系统(业务逻辑条件判断最佳实践)
这篇文章其实是大健康行业直销系统的番外篇,主要给大家讲讲如何在领域逻辑中,有效的处理业务逻辑条件判断的最佳实践问题. 大家都知道,聚合根.实体和值对象这些领域对象都自身处理自己的业务逻辑.在业务处理过 ...
- DDD实战进阶第一波(三):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架二)
了解了DDD的好处与基本的核心组件后,我们先不急着进入支持DDD思想的轻量级框架开发,也不急于直销系统需求分析和具体代码实现,我们还少一块, 那就是经典DDD的架构,只有了解了经典DDD的架构,你才能 ...
- DDD实战进阶第一波(十五):开发一般业务的大健康行业直销系统(总结篇)
前面我们花了14篇的文章来给大家介绍经典DDD的概念.架构和实践.这篇文章我们来做一个完整的总结,另外生成一个Api接口文档. 一.DDD解决传统的开发的几大问题: 没有描述需求的设计模型:而是直接通 ...
- DDD实战进阶第一波(十二):开发一般业务的大健康行业直销系统(订单上下文POCO模型)
在本系列前面的文章中,我们主要讨论了产品上下文与经销商上下文相关的实现,大家对DDD的方法与架构已经有了初步的了解. 但是在这两个界限上下文中,业务逻辑很简单,也没有用到更多的值对象的内容.从这篇文章 ...
- DDD实战进阶第一波(十四):开发一般业务的大健康行业直销系统(订单上下文应用服务用例与接口)
上一篇文章我们主要讲了订单上下文的领域逻辑,在领域逻辑中完成了订单项的计算逻辑.订单的计算逻辑以及如何生成相应的实体code,这篇文章我们通过 在应用服务中实现一个下单的用例,来将这些领域逻辑以及仓储 ...
- DDD实战进阶第一波(五):开发一般业务的大健康行业直销系统(实现产品上下文领域层)
从这篇文章开始,我们根据前面的DDD理论与DDD框架的约束,正式进入直销系统案例的开发. 本篇文章主要讲产品上下文中的领域层的主要实现,先简单讲下业务方面的需求:产品SPU与产品SKU,产品SPU主要 ...
- DDD实战进阶第一波(六):开发一般业务的大健康行业直销系统(实现产品上下文仓储与应用服务层)
前一篇文章我们完成了产品上下文的领域层,我们已经有了关于产品方面的简单领域逻辑,我们接着来实现产品上下文关于仓储持久化与应用层的用例如何来协调 领域逻辑与仓储持久化. 首先大家需要明确的是,产品上下文 ...
随机推荐
- JavaScript进阶(一)抽离公共函数
JS抽离公共函数 问题 在经历了"大量"的项目开发后,发觉越来越多的方法可以被抽离出来作为一个公共方法使用.那么,在js中该思想又该如何实现呢? 解答 例如,以下方法用于实现将标准 ...
- VisualSVN Server安装过程
运行VisualSVN-Server-2.7.3.msi程序, 如下图 点击Next, 下一步 选中 I accept选项, 点击Next, 下一步 选择默认配置, 服务和控制台组件方式, 点击 ...
- Java学习笔记(一)网格袋布局
网格袋布局类似于Win8的Metro布局,用于将组件按大小比例放在不同位置的网格内,各组件的实际大小会随着窗口的改变而改变,但相对位置不变,能够很好的适应屏幕. 通过阅读<21天学通Java&g ...
- 使用SVM对多类多维数据进行分类
最近,本人要做个小东西,使用SVM对8类三维数据进行分类,搜索网上,发现大伙讨论的都是二维数据的二分类问题,遂决定自己研究一番.本人首先参考了opencv的tutorial,这也是二维数据的二分类问题 ...
- 中国象棋游戏Chess(2) - 走棋
之前的文章请看:中国象棋游戏Chess(1) - 棋盘绘制以及棋子的绘制 现在实现走棋的功能. 首先需要获取点击到的棋子,用QWidget中的函数 mouseReleaseEvent 实现函数: vo ...
- 数据库用户映射到SQL Server登录名
由于不是固定在一如电脑开始,经常需要把数据备份与恢复.或者是帮助客户修改程序,接收到客户备份好的数据,需要在电脑恢复. 这样就需要将数据库用户映射到 SQL Server 登录名.如何映射?可使用下面 ...
- 不错的网络协议栈测试工具 — Packetdrill
Packetdrill - A network stack testing tool developed by Google. 项目:https://code.google.com/p/packetd ...
- "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: no freetype in java.library.path
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: no freetype in java ...
- C#中使用双缓冲来避免绘制图像过程中闪烁
自己所做项目中,在显示医学图像的界面中,当鼠标拖动图像时,不断刷新从后台获取新的图像,而整个过程就很诡异,一直闪个不停. 找到的一个可行方法是:在用户控件的构造函数中加入以下代码: SetStyle( ...
- 简单了解JS中的几种遍历
忙了好一段时间,项目上线后终于有那么一点点空档期静下来整理一些问题了.当我们在开发项目的时候,用到遍历的地方肯定少不了,那么我们有那么多的遍历方法,在不同情况下用那种方法会更优雅而且还没bug呢? 首 ...