用Abp实现短信验证码免密登录(二):改造Abp默认实现

Abp 实现通过手机号注册用户 Python微信订餐小程序课程视频 https://blog.youkuaiyun.com/m0_56069948/article/details/122285951 Python实战量化交易理财系统 https://blog.youkuaiyun.com/m0_56069948/article/details/122285941 前言 Abp 的 Identity 模块,实现了用户的管理,但是对于国内来讲,很多场景不能很好适配。比如:通过手机号进行注册的场景。 Abp vnext Identity 以及 asp.net core 阅读详情


接下来我们重写原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
  },

至此,后端的所有任务结束,下一章将介绍前端项目的搭建

项目地址

Github:matoapp-samples

ABP Vnext 学习02-授权中心 重写Login 页面 实现的方式也有其他的方式 可能不是最优 如果有兴趣的可以自己研究 ;1 首先看他们Abp 的官方文档 其中介绍的已经适用于一部分场景 官方文档的三种介绍 1 仅重写页面模型(C#)端执行其他逻辑,不更改UI. 2 仅重写Razor页面(.cshtml文件),不更改逻辑. 3 完全重写 页面. 重写页面 Account Login 页面 默认会覆盖原有的 和逻辑就可以根据这个继承的 MyLoginModel 来 切入 也可以完全重写 可以根据文档上的继承 PageModel,AbpPageModel 阅读详情

相关推荐

Abp vNext实现登录返回token可调用其他接口

/必须加上项目和数据库里定义得授权范围,否则登录成功后还是提示401。只是验证登录,并不返回token。Abp中获取token的接口是。具体使用方式看官方文档的。部分,我就记录一些常用的。

weixin_38225763的博客 3080

使用 Abp.Zero 搭建第三方登录模块(四):微信小程序开发

微信小程序主要为用户授权行为提供交互功能,用户在扫码之后,提供一个交互UI,如下在中介绍了服务端已经搭建的接口,这次我们将调用Access和Authenticate,分别调用来完成已扫码和已授权状态的更新。......

jevonsflash的专栏 745

abp vnext框架自定义扩展volo.abp.openiddict的登录验证

在 ABP vNext 框架下,可以通过扩展 OpenIddict 的 ITokenExtensionGrant 接口来自定义登录验证逻辑

滴水成河,汇流成海 1037

手工搭建基于ABP的框架(3) - 登录,权限控制与日志

为了防止不提供原网址的转载,特在这里加上原文链接: http://www.cnblogs.com/skabyy/p/7695258.html 本篇将实现登录、权限控制、日志配置与审计日志的功能。首先我们先实现登录功能,在登录的基础上,通过控权使得只有ID为1988的用户才能创建tweet。最后配置Log4Net日志,并开启审计日志,记录所有Web请求。 简单的界面 为了测试方便,在实现登录功能...

weixin_30663471的博客 1320

零代码搭建专业知识库:Wiki.js+cpolar让团队协作像写笔记一样简单

"项目文档又找不到了!“团队负责人小张第N次在群里看到这样的抱怨——技术文档分散在邮件、网盘和个人电脑里,新人入职要花一周熟悉文档位置,远程协作时版本混乱更是家常便饭。Wiki.js与cpolar内网穿透服务的出现,就像给团队协作装上了"中央大脑”,用写Markdown笔记的简单方式,搭建一个专业的知识库系统。普通人对知识管理的需求其实很简单:方便记录、容易查找、大家能用。但传统方案把这个过程搞得异常复杂:建服务器、配环境、学语法、搞权限……大部分团队还没开始就放弃了。

Yawesh的博客 2040

从AMBA到USB:手把手教你评估和选择Synopsys DesignWare里的免费商用IP

本文详细介绍了如何评估和选择Synopsys DesignWare中的免费商用IP,从AMBA到USB等关键模块。通过技术参数核对、验证环境评估和集成注意事项,帮助工程师高效利用这些经过硅验证的商业级IP,提升SoC设计效率。文章还探讨了免费IP与付费IP的边界策略,避免常见陷阱。

weixin_42683394的博客 297

用Abp实现短信验证码免密登录(一):短信校验模块

这是一篇系列博文,我将使用Abp.Zero搭建一套集成手机号免密登录验证与号码绑定功能的用户系统:第三方身份验证在Abp中称之为, 区别于Abp的,这里Auth的全称应为Authorization,即授权。首先来厘清这两个不同的业务在Abp中的实现,我之前写的这篇系列文章中描述的业务,即使用的Abp外部身份授权(ExternalAuth)的相关扩展而实现的。还记得我们实现的WeChatAuthProvider吗?它继承于ExternalAuthProviderApi这个抽象类,实现的微信授权功能。

jevonsflash的专栏 1675

中移物联ML307C模组OPENCPU开发环境搭建全攻略

本文详细介绍了中移物联ML307C模组OPENCPU开发环境搭建的全过程。从OPENCPU模式的核心优势解析,到SDK获取、Python与scons工具安装,再到解读SDK目录结构与实战编译命令,最后提供常见问题避坑指南,帮助开发者快速构建高效的物联网应用编译环境。

weixin_29168393的博客 745

用Abp实现两步验证(Two-Factor Authentication,2FA)登录(一):认证模块

创建方法IsTwoFactorAuthRequiredAsync,返回登录用户是否需要双因素认证,若未开启TwoFactorLogin.IsEnabled、用户未开启双因素认证,或没有添加验证提供者,则跳过双因素认证。双因素认证(Two-Factor Authentication,简称 2FA)是使用两个或多个因素的任意组合来验证用户身份,例如用户提供密码后,还要提供短消息发送的验证码,以证明用户确实拥有该手机。至此,双因素认证的后端逻辑已经完成,接下来我们将补充“记住”功能,实现一段时间内免验证。

jevonsflash的专栏 2275

AI大模型开发——transformer模型超全完整版(0基础可懂)

为了更深入的了解transformer模型,我们首先从transformer的诞生聊起吧。transformer在2017年由Vaswani等人首次提出,它摒弃了之前流行的循环神经网络和卷积神经网络的架构,引入了自注意力机制( Self-Attention),显著提高了处理序列数据的能力和效率。transformer模型的这种设计使其在处理长距离依赖问题时, 相比于传统的循环神经网络和长短期记忆网络(LSTM)表现得更加出色,至此, 开启了NLP技术的新篇章。

m0_74922316的博客 2120

ROS与UR10e机械臂实战:从零搭建到精准控制

本文详细介绍了如何从零开始搭建ROS与UR10e机械臂的开发环境,包括硬件准备、软件配置、网络设置以及MoveIt!运动控制实战。通过具体的代码示例和常见问题排查,帮助开发者快速掌握UR10e机械臂的精准控制技术,适用于工业自动化和实验室研究场景。

m3n5b7v8c9x的博客 772

用Abp实现短信验证码免密登录(三):Vue网页端开发

前端代码的框架采用vue.js + elementUI 这套较为简单的方式实现,以及typescript语法更方便阅读。首先来编写发送验证码函数。注意几个关键的全局变量。

jevonsflash的专栏 714

本文将详细介绍如何在 Qt (C++) 应用程序中集成 osgEarth,加载三维数字地球,并在指定经纬度添加三维模型(如飞机、建筑等)。

OSG 与 Qt 的交互通常需要处理 OpenGL 上下文。osgEarth 3.x 提供了对 Qt 的较好支持,或者可以使用。在普通 OSG 程序中,你需要手动处理坐标系转换将经纬度转为笛卡尔坐标 (XYZ)。这是实现的关键,将 OSG 的渲染循环集成到 Qt 的事件循环中。第三方库,但在本教程中,我们将展示一种通过继承。,将 Qt 的输入事件转换为 OSG 理解的。事件,这是实现交互(旋转地球、缩放)的基础。来嵌入 OSG 视图的标准方法。在这里我们初始化地球并添加模型。节点简化了这一过程。

qq_45859163的博客 1045

新建一个项目,如何使用abp用户登录系统

1、首先参考Framework.Web里的packages.config,把相关的包都安装好。 2、App_Start文件夹下的xxxModule.cs和Startup.cs拷过来,修改下命名空间。 3、Controllers里的Result文件夹、ControllerBase.cs、AccountController.cs拷过来,修改下命名空间。 4、在需要登录才能访问的cont...

weixin_30627341的博客 1818

Power Switch与Tap Cell关系

tap cell可以选用一般类型的tap cell,无须secondary pg pin,因为此时switch cell的阱电位接到输入power net上了,switch cell可以正常上电,也可以给core内正常供电,tap cell的阱电位接switch cell输出的power,需要注意的是此时switch cell与core内其他cell的阱电位是不同的,所以为了避免drc问题,需要在switch上盖hard blockage或者keepout margin。2)自带阱偏置的switch。

m0_61544122的博客 2337

Allan方差这个工具,怎么把它用的更顺手?(附Allan方差、动态Allan方差代码)

本文详细说明了Allan方差和动态Allan方差的计算过程,并通过递归运算和时间序列选择两种算法提高动态Allan方差的计算效率。文末提供了快速动态Allan方差计算代码。

victoryqian528的博客 374

Asp.NET Core+ABP框架+IdentityServer4+MySQL+Ext JS之登录、权限、菜单和登出

尝试新的开发组合:Asp.NET Core+ABP框架+IdentityServer4+MySQL+Ext JS Asp.NET Core+ABP框架+IdentityServer4+MySQL+Ext JS之配置IdentityServer Asp.NET Core+ABP框架+IdentityServer4+MySQL+Ext JS之数据迁移 Asp.NET Core+ABP框架+Ident

黄灯桥的专栏 5468

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

abp中多种登陆用户的设计

场景 在《学校管理系统》中,学生、家长、教师、教务都可能登陆,做一些属于他们自己的操作。这些用户需要的属性各不相同,比如学生有学号,而教师没有。 应用程序用户 在编码时,经常需要获取当前登陆用户的信息,这个当前登陆用户就是应用程序用户。asp.net提供了一整套方案来实现应用程序用户,包括身份验证、授权、asp.net identity等 应用程序用户与业务场景中的用户不同,应用程序用户只需要区别是谁,最简单情况只需要知道用户id,它不关心这个用户具体是教师还是学生或其它类型的用户。基于这个用户id还可以.

zhoumouren88的博客 1633

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

企业级工作流解决方案(十二)--集成Abp和ng-alain--用户身份认证与权限验证

多租户   如果系统需要支持多租户,那么最好事先定义好多租户的存储部署方式,Abp提供了几种方式,根据需要选择,每一个用户身份认证与权限验证都需要完全的隔离   这里设计的权限数据全部存储在缓存中,每个租户单独建立缓存Key,见权限系统服务章节介绍。 用户accesstoken   accesstoken的定义就不多的介绍了,Abp其实就是直接使用微软IdentityModel这套组件,并...

weixin_34121304的博客 1046

Asp.net core abp 无密码登录

需求是Asp.net core abp 无密码登录 具体是另外一个系统跳转到我这个系统需要做一个无密码登录,免登录的效果。 但它那个是java系统,授权也不一样,无法共用验证。 所以我在本系统增加了同步用户功能,把那边账户同步过来,租户信息也同步过来。 java系统传租户Id和用户的登录名过来,我这通过验证,返回token,以下是核心代码,就是改造了一下Authenticate。 TokenAuthController.cs文件 [HttpPost] public asyn...

Martin 的博客 1086

用Abp实现两步验证(Two-Factor Authentication,2FA)登录(三):免登录验证

常用的实现方式是在用户登录成功后,生成一个随机的字符串Token,将此Token保存在用户浏览器的 cookie 中,同时将这个字符串保存在用户的数据库中。当用户再次访问时,如果 cookie 中的字符串和数据库中的字符串相同,则免登录验证通过。rememberClientToken是存储于cookie中的,当用户登出时不需要清空cookie中的rememberClientToken,以便下次登录跳过两步验证。为了安全,Token采用对称加密传输存储,同时参与校验的还有用户Id,以进一步验证数据一致性。

jevonsflash的专栏 2223

使用 Abp.Zero 搭建第三方登录模块(二):服务端开发

微信SDK库是针对微信相关 API 进行封装的模块 ,目前开源社区中微信SDK库数量真是太多了,我选了一个比较好用的EasyAbp WeChat库。EasyAbp/Abp.WeChat: Abp 微信 SDK 模块,包含对微信小程序、公众号、企业微信、开放平台、第三方平台等相关接口封装。 (github.com)当然这个库是ABP vNext 框架的,需要稍微改写一下。封装好后我们需要以下几个接口小程序码生成接口: 获取用户OpenId与SessionKey的接口 我们先来回顾一下第三方登录在Ab

jevonsflash的专栏 1109

abp vnext 8.0 微信小程序 第三方登录 connect/token的扩展实现 OpenIddect

abp vnext 8.0 微信小程序登陆 提示 The Specified GrantType Is NotImplemented 错误的解决办法,第三方登陆扩展,abp 微信小程序登陆, abp 微信小程序 connct/token ,abp 第三方登陆,abp 第三方登陆 connct/token

hanxiao1224的专栏 1888

ABP vNext 拓展短信授权登陆

今天,准备在ABP vNext上拓展一下短信登录,流程很简单:用户请求发送验证码接口,后台生成验证码,然后发送到用户手机,用户收到验证码,使用拓展授权方式SMSGrantType获取令牌,完成授权。 首先,关于验证码生成,为了避免生成存储到本地再校验一般采用TOTP加密算法,它是基于时间的一次性密码生成算法,由RFC6238定义。和基于事件的一次性密码生成算法不同HOTP,TOTP是基于时间的,在有效时间过后,针对同一用户所生成的验证码将会发生改变。 AspNetCore已经在其TOTP- (...

神奇海螺 2177

号称第三方授权登录终结者!支持各大平台,便捷实用,让登录变得So easy!(带私活源码)

它仅仅是一个第三方授权登录的工具类库,它可以让我们脱离繁琐的第三方登录 SDK.,让登录变得So easy!

m0_68103666的博客 1586
上一篇: 用Abp实现短信验证码免密登录(一):短信校验模块
下一篇: 用Abp实现短信验证码免密登录(三):Vue网页端开发
林晓lx
林晓lx 2017年优快云移动跨平台大赛优秀奖获得者 2017年优快云移动跨平台大赛优秀奖获得者
博客等级 码龄15年 3761粉丝 123原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林晓lx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值