Abp 实现通过手机号注册用户
前言
Abp 的 Identity 模块,实现了用户的管理,但是对于国内来讲,很多场景不能很好适配。比如:通过手机号进行注册的场景。
Abp vnext Identity 以及 asp.net core identity 默认只有 Email 必填以及唯一的校验,缺少手机号必要的校验;对此我们需要进行适当的调整,以作适配。
准备
建议先参考 IdentityUserAppService 对用户注册的实现;
由于手机号验证的场景基本上是需要的,所以本次采用重写的方式,当然也可以参考其代码,自定义自己的实现。
Application
public class PublicAccountAppService: IdentityUserAppService
{
public PublicAccountAppService(
IdentityUserManager userManager,
IIdentityUserRepository userRepository,
IIdentityRoleRepository roleRepository,
IOptions<IdentityOptions> identityOptions)
: base(userManager, userRepository, roleRepository, identityOptions)
{ } public override async Task<IdentityUserDto> CreateAsync(
IdentityUserCreateDto input)
{
ValidateRegisterInput(input);
await CheckRegisterableByPhone(input.PhoneNumber);
return await base.CreateAsync(input);
} private static void ValidateRegisterInput(IdentityUserCreateDto input)
{
if (input.PhoneNumber.IsNullOrWhiteSpace())
{
throw new AbpValidationException(
"Phone number is required for new users!",
new List<ValidationResult>
{
new ValidationResult(
"Phone number can not be empty!",
new []{"PhoneNumber"}
)
}
);
}
} private async Task CheckRegisterableByPhone(string phoneNumber)
{
var isPhoneNumberExist = await _accountRepository.IsPhoneNumberExistAsync(phoneNumber);
if (isPhoneNumberExist)
{
throw new AbpValidationException(
"Phone number already exist!",
new List<ValidationResult>
{
new ValidationResult(
"Phone number already exist!",
new []{"PhoneNumber"}
)
}
);
}
}
}
Domain
由于 IIdentityUserRepository 缺少对手机号是否存在的默认实现,我们可以新增对应Repository 来实现相关功能。
尽量遵守DDD 分层的原则。

1 public interface IAccountRepository
2 {
3 Task<bool> IsPhoneNumberExistAsync(string phoneNumber);
4 }
Repository
实现Domain 层定义的接口

1 public class AccountRepository: IAccountRepository, ITransientDependency
2 {
3 private readonly IRepository<IdentityUser, Guid> _identityUserRepository;
4
5 public AccountRepository(IRepository<IdentityUser, Guid> identityUserRepository)
6 {
7 _identityUserRepository = identityUserRepository;
8 }
9
10 public async Task<bool> IsPhoneNumberExistAsync(string phoneNumber)
11 {
12 return await _identityUserRepository.AnyAsync(
13 c => c.PhoneNumber == phoneNumber);
14 }
15 }
替换默认实例
我们已经完成了对 IdentityUserAppService 创建方法的重写,需要替换默认的接口实例对象,可以参考 Customizing Application Modules Overriding Services | Documentation Center | ABP.IO

[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IIdentityUserAppService), typeof(IdentityUserAppService), typeof(PublicAccountAppService))]
public class PublicAccountAppService: IdentityUserAppService
{...}
其他
主要的修改已经调整完毕。但是由于AbpUser 表没有 PhoneNumber 的相关索引,可以自行通过 Migration 进行添加。
Abp 框架比较优秀,很多方面也算是最佳实践,推荐使用。
改动比较小,修改起来也比较方便;当然也可以完全重写 注册的方法。下次有时间可以再整理下通过手机号登陆的实现。
Abp 实现通过手机号注册用户的更多相关文章
- java在线聊天项目 客户端登陆窗口LoginDialog的注册用户功能 修改注册逻辑 增空用户名密码的反馈 增加showMessageDialog()提示框
LoginDialog类的代码修改如下: package com.swift.frame; import java.awt.EventQueue; import java.awt.event.Acti ...
- 在Django中进行注册用户的邮件确认
之前利用Flask写博客时(http://hbnnlove.sinaapp.com),我对注册模块的逻辑设计很简单,就是用户填写注册表单,然后提交,数据库会更新User表中的数据,字段主要有用户名,哈 ...
- Servlet页面注册用户的小程序(一)
本实例实现用userreg.jsp页面中的表单提交注册请求,把注册信息提交给regservlet写入数据库并且查询新用户显示出来. 一.准备工作. 1.jdbc数据驱动开发包mysql-connect ...
- Textview下划线注册用户跳转实现
在xml中: <TextView android:id="@+id/textView_regtext" android:layout_width="wrap_con ...
- WordPress 前端投稿/编辑插件 DJD Site Post(支持游客和已注册用户)
转自:http://www.wpdaxue.com/front-end-publishing.html 说到前端用户投稿,倡萌之前推荐过3个不错的插件: WordPress匿名投稿插件:DX-Cont ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(17)-注册用户功能的细节处理(各种验证)
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(17)-注册用户功能的细节处理(各种验证) ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框 ...
- SpringBoot对注册用户密码进行Bcrypt密码加密
一.注册用户时,用户的密码一般都是加密存储在数据库中.今天我要用到的加密方式是Bcrypt加密. 1.首先在SpringBoot项目的pom文件中,引入SpringSecurity相关依赖,目的是为了 ...
- Django中,ajax检测注册用户信息是否可用?
ajax检测注册用户信息主体思路 1.在settings.py中配置需要使用的信息 #对static文件进行配置 STATICFILES_DIRS=[ os.path.join(BASE_DIR,'s ...
- 如何在Web.config中注册用户控件和自定义控件
问题: 在ASP.NET 的早先版本里,开发人员通过在页面的顶部添加 指令来引入和使用自定义服务器控件和用户控件时,象这样: <%@ Register TagPrefix="scott ...
随机推荐
- 报错————Type interface com.ssm.mapper.NewProductMapper is not known to the MapperRegistry.
报错: Exception in thread "main" org.apache.ibatis.binding.BindingException: Type interface ...
- 开启路由器的TCP拦截
TCP拦截即TCP intercept,大多数的路由器平台都引用了该功能,其主要作用就是防止SYN泛洪攻击.SYN攻击利用的是TCP的三次握手机制,攻击端利用伪造的IP地址向被攻击端发出请求,而被攻击 ...
- Twist the Permutation 数列的轮换题 Codeforces 776 div3
这是一道比较经典的将数列中的数字轮换的题目,我们先看题干: 题干分析:先浅浅地分析一下题目是要我们干什么,我们会默认有一个已经升序排序地1~n的排列,然后我们会给定一个新排列是在原有排列的基础上进行o ...
- 集合 copy
#集合的创建 # set = set(["barry",1,2]) # print(set) # set1 = {1,2,3} #集合的增 # set1 = {'alex','wu ...
- iOS全埋点解决方案-应用退出和启动
前言 通过应用程序退出事件,可以分析应用程序的平均使用时长:通过应用程序的启动事件,可以分析日活和新增.我们可以通过全埋点方式 SDK 实现应用程序的退出和启动事件. 一.全埋点的简介 目前. ...
- 半吊子菜鸟学Web开发 -- PHP学习 4 --异常
PHP异常处理 1 抛出一个异常 与Python的try except类似,PHP用try catch来捕获异常 基本语法 try{ //可能出现错误或异常的代码 //catch表示捕获,Except ...
- C++各种输入
https://blog.csdn.net/qq_29735775/article/details/81165882 1.cin 2.cin.get() 3.cin.getline() 4.getli ...
- linux上使用nginx、uwsgi部署django项目
参考:CentOS7下部署Django项目详细操作步骤 注意事项: 在虚拟环境中操作,虚拟环境中安装nginx.uwsgi,虚拟环境外需安装uwsgi -- 临时关闭防火墙:systemctl sto ...
- Python form...import...和import的区别(自己理解的)
Python有两种导入包和模块的方式,区别如下 form...import... import 相对导包 导入不同包子模块 可以导入模块所需变量/函数/类 init文件的__all__特殊变量(模 ...
- 学习FastDfs(一)
一.简介 FastDFS是一个开源的轻量级分布式文件系统,由跟踪服务器(tracker server).存储服务器(storage server)和客户端(client)三个部分组成 fastfds有 ...