Abp.Zero 手机号免密登录验证与号码绑定功能的实现(二):改造Abp默认实现
接下来我们重写原Abp的部分实现,来驳接手机号相关业务。
改造User类
重写PhoneNumber使得电话号码为必填项,和中国大陆手机号11位长度
public new const int MaxPhoneNumberLength = 11;
[Required]
[StringLength(MaxPhoneNumberLength)]
public override string PhoneNumber { get; set; }
改造UserStore类
扩展通过PhoneNumber查找用户的方法
public async Task<User> FindByNameOrPhoneNumberAsync(string userNameOrPhoneNumber)
{
return await UserRepository.FirstOrDefaultAsync(
user => user.NormalizedUserName == userNameOrPhoneNumber || user.PhoneNumber == userNameOrPhoneNumber
);
}
[UnitOfWork]
public async Task<User> FindByNameOrPhoneNumberAsync(int? tenantId, string userNameOrPhoneNumber)
{
using (_unitOfWorkManager.Current.SetTenantId(tenantId))
{
return await FindByNameOrPhoneNumberAsync(userNameOrPhoneNumber);
}
}
改造UserManager类
添加检测重复电话号码的方法CheckDuplicateUsernameOrPhoneNumber
public async Task<IdentityResult> CheckDuplicateUsernameOrPhoneNumber(long? expectedUserId, string userName, string phone)
{
var user = await FindByNameAsync(userName);
if (user != null && user.Id != expectedUserId)
{
throw new UserFriendlyException(string.Format(L("Identity.DuplicateUserName"), userName));
}
user = await FindByNameOrPhoneNumberAsync(GetCurrentTenantId(), phone);
if (user != null && user.Id != expectedUserId)
{
throw new UserFriendlyException("电话号码重复", phone);
}
return IdentityResult.Success;
}
重写对用户的Create和Update,使其先检测是否重复电话号码。
//override
public override async Task<IdentityResult> CreateAsync(User user)
{
var result = await CheckDuplicateUsernameOrPhoneNumber(user.Id, user.UserName, user.PhoneNumber);
if (!result.Succeeded)
{
return result;
}
return await base.CreateAsync(user);
}
public override async Task<IdentityResult> UpdateAsync(User user)
{
var result = await CheckDuplicateUsernameOrPhoneNumber(user.Id, user.UserName, user.PhoneNumber);
if (!result.Succeeded)
{
return result;
}
return await base.UpdateAsync(user);
}
改造LogInManager类
分别重写LoginAsyncInternal,TryLoginFromExternalAuthenticationSourcesAsync两个方法,在用Email找不到用户之后,添加用手机号码查找用户的逻辑,添加的代码如下:
...
if (user == null)
{
user = await userManager.FindByNameOrPhoneNumberAsync(tenantId, combinationName);
}
编写验证源
新建电话号码验证源类PhoneNumberExternalAuthenticationSource,并实现验证码校验逻辑,具体的代码
public class PhoneNumberExternalAuthenticationSource : DefaultExternalAuthenticationSource<Tenant, User>, ITransientDependency
{
private readonly CaptchaManager captchaManager;
public PhoneNumberExternalAuthenticationSource(CaptchaManager captchaManager)
{
this.captchaManager=captchaManager;
}
/// <inheritdoc/>
public override string Name { get; } = "SMS验证码登录";
/// <inheritdoc/>
public override async Task<bool> TryAuthenticateAsync(string phoneNumber, string token, Tenant tenant)
{
//for test
//return true;
var currentItem = await captchaManager.GetToken(token);
if (currentItem==null || currentItem.PhoneNumber!=phoneNumber || currentItem.Purpose!=CaptchaPurpose.LOGIN)
{
return false;
}
await captchaManager.RemoveToken(token);
return true;
}
/// <inheritdoc/>
public override Task<User> CreateUserAsync(string userNameOrEmailAddress, Tenant tenant)
{
var seed = Guid.NewGuid().ToString("N").Substring(0, 7);
var surname = "手";
var name = "机用户"+seed;
var userName = PinyinUtil.PinYin(surname+name);
var result = new User()
{
Surname = surname,
Name = name,
UserName = userName,
IsPhoneNumberConfirmed = true,
IsActive=true,
TenantId = tenant?.Id,
PhoneNumber = userNameOrEmailAddress,
Settings = null,
IsEmailConfirmed = true,
EmailAddress=$"{userName}@abc.com"
};
return Task.FromResult(result);
}
/// <inheritdoc/>
public override Task UpdateUserAsync(User user, Tenant tenant)
{
return Task.FromResult(0);
}
}
配置
在Web.Core项目中的WebCoreModule文件中,将PhoneNumberExternalAuthenticationSource添加至扩展身份验证源配置中
private void ConfigureExternalAuth()
{
var userManagementConfig = IocManager.Resolve<IUserManagementConfig>();
userManagementConfig.ExternalAuthenticationSources.Add(typeof(PhoneNumberExternalAuthenticationSource));
}
在Web.Host项目中的 appsettings.json 文件中,添加AliyunSms库的相关配置,详细说明请参考AbpBoilerplate.Sms。
"AliyunSms": {
"RegionId": "cn-hangzhou",
"AccessKey": "{Your AccessKey}", //阿里云后台管理页面中获取AccessKey
"AccessKeySecret": "{Your AccessKeySecret}" //阿里云后台管理页面中获取AccessKeySecret
},
至此,后端的所有任务结束,下一章将介绍前端项目的搭建
项目地址
Abp.Zero 手机号免密登录验证与号码绑定功能的实现(二):改造Abp默认实现的更多相关文章
- Abp.Zero 手机号免密登录验证与号码绑定功能的实现(一):验证码模块
这是一篇系列博文,我将使用Abp.Zero搭建一套集成手机号免密登录验证与号码绑定功能的用户系统: Abp.Zero 手机号免密登录验证与号码绑定功能的实现(一):验证码模块 Abp.Zero 手机号 ...
- linux免密登录ssh验证配置方法及常见错误解决
目标:从服务器A免密登录服务器B [配置方法] 1.在服务器A生成密钥文件,直接使用以下命令: ssh-keygen 中间遇到输入内容一路回车即可,完成后会在 ~/.ssh 目录下生成两个文件:id_ ...
- 1.配置桥接,并抓包验证 2.实现免密登录 3.修改登录端口: 22-》2222 4.不允许root用户远程登录 5.创建用户sshuser1,并设置密码,且只允许sshuser1远程ssh登录
1.配置桥接: 抓包时如果有ens160的ICMP,说明我们的桥接搭建成功通过桥接访问到了ens160(这里忘加图片了) (1)创建一个桥接设备和会话 (2)添加设备和会话到桥接设备上 (3)启动从 ...
- 基于vagrant工具在win7下免密登录linux
一.SSH加密方式 SSH采用的是"非对称密钥系统",即耳熟能详的公钥私钥加密系统,其安全验证又分为两种级别. 1. 基于口令的安全验证 这种方式使用用户名密码进行联机登录,一般情 ...
- linux(十)配置ssh免密登录实现
知道ssh的朋友应该知道它是用来干什么的,如果你不知道什么是ssh远程登录的话,可以去看一下我的上一篇博客,关于linux的网络基础的知识.备注:ssh是用于远端登入.执行ssh指令开启终端机阶段作业 ...
- 【图文详解】linux下配置远程免密登录
linux下各种集群搭建往往需要配置远程免密登录,本文主要描述了CentOs6.3系统下配置免密登录的详细过程. ssh远程登录,两种身份验证: 用户名+密码 密钥验证 机器1生成密钥对并将公钥发给机 ...
- (11)ssh免密登录配置
***在Linux命令行中登录到另一台虚拟机(需要用到ssh协议) Linux中默认有ssh的服务器端和客户端,客户端的名字就叫ssh 前提是当前使用的用户名在待连接的虚拟机中存在 格式: ssh ...
- CentOS7+CDH5.14.0安装全流程记录,图文详解全程实测-2设置SSH免密登录
因为hadoop集群在安装的时候需要集群中所有机器的权限. 所以我们需要打通所有节点的ssh无密码登陆,思路是生成每台机子的密钥,集中在一个文件中,再分发到每台机子上. 为了确保下面的命令能顺利执行, ...
- Ubuntu 开启SSH服务以及有关设置:安装,指定端口号、免密登录、远程拷贝
本文所用系统为 Ubuntu 18.04 什么是SSH? 简单说,SSH是一种网络协议,用于计算机之间的加密登录.全名为:安全外壳协议.为Secure Shell的缩写.SSH为建立在应用 ...
- linux上ssh免密登录原理及实现
因为我的服务器集群需要回收日志到中央进行统一处理,所以需要建立ssh互信关系实现免密登录.关于ssh的使用大家可能都很熟悉了,我们今天主要来讲下ssh连接和免密登录的原理. scp 传输文件 scp( ...
随机推荐
- 事务提交之后再执行某些操作 → 引发对 TransactionSynchronizationManager 的探究
开心一刻 昨晚,小妹跟我妈聊天 小妹:妈,跟你商量个事,我想换车,资助我点呀 妈:哎呀,你那分扣的攒一堆都够考清华的,还换车资助点,有车开就不错了 小妹:你要是这么逼我,别说哪天我去学人家傍大款啊 妈 ...
- 使用三方jar中的@RestControllerAdvice不起作用
背景 公司封装了自己的基础核心包core-base,里边包含了Validation的异常捕获处理类:同时开发项目有全局异常捕获处理类,经测试发现,core-base里边的不起作用 可能原因: 未扫描外 ...
- Flask 实现Token认证机制
在Flask框架中,实现Token认证机制并不是一件复杂的事情.除了使用官方提供的flask_httpauth模块或者第三方模块flask-jwt,我们还可以考虑自己实现一个简易版的Token认证工具 ...
- STM32CubeMX教程29 USB_HOST - 使用FatFs文件系统读写U盘
1.准备材料 正点原子stm32f407探索者开发板V2.4 STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) ST-LINK/V2驱动 ...
- UIWindow的概念与使用
UIWindow的作用 UIWindow是UIView的子类用于显示程序内容.每一个UIView想要将内容显示到屏幕上都需要依赖于一个UIWindow. iOS应用程序要想正常运行至少要有一个UIWi ...
- 【栈和队列】纯C实现栈和队列以及其基本操作-宝藏级别数据结构教程【保姆级别详细教学】
[栈和队列]栈和队列的C语言实现-宝藏级别数据结构教程-超详细的注释和解释 先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力 看完之后别忘记 ...
- 单片机 IAP 技术方案设计
1.前言 关于 IAP 技术,做过 bootloader 的想必很熟悉 (IAP全称 In Application Programming,即应用编程),和 ISP (全称 In System Pro ...
- 硬件、OS、数据库各种兼容性傻傻分不清?
服务器硬件型号.OS操作系统版本.Oracle数据库版本.. 各种型号各种版本,排列组合的话也是N多种组合,如何确认这些可以兼容并且得到官方认证呢? 其实很简单,各司其职,各自去确认各自的. 我们知道 ...
- Spring Boot 参数校验注解(自整理,不停的测试更新)
首先我们只使用java官方的 javax.validation.constraints ,足以使用了,不使用spring boot 自身的,自身的与官方的一致,可能会有扩展,但是还得引入包,麻烦,只用 ...
- 【CAS学习一】CAS服务端部署
公司要做单点登录系统,网上搜了一下目前主流方案是CAS,故部署一个试试看. 1.下载 因为最近出现log4j2远程代码执行漏洞,尽量选择新版本已修复此漏洞的,故CAS选择6.4版本.打包部署依赖JDK ...