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

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


这是一篇系列博文,我将使用Abp.Zero搭建一套集成手机号免密登录验证与号码绑定功能的用户系统:

原理

第三方身份验证在Abp中称之为外部身份验证(ExternalAuthentication), 区别于Abp的外部身份授权(ExternalAuth),这里Auth的全称应为Authorization,即授权。

首先来厘清这两个不同的业务在Abp中的实现,我之前写的这篇 Abp.Zero 搭建第三方登录模块 系列文章中描述的业务,即使用的Abp外部身份授权(ExternalAuth)的相关扩展而实现的。还记得我们实现的WeChatAuthProvider吗?它继承于ExternalAuthProviderApi这个抽象类,实现的微信授权功能。所以微信登录这个动作,实际是在授权(Authorization)已有的微信账号,访问服务端资源,而身份验证(Authentication)步骤,已在其他端完成了(手机微信扫码),在服务端获取已验证好身份的第三方账户并生成Token则可以抽象的认为是授权(Authorization)行为。

所以“搭建第三方登录模块”应该更准确地描述为“第三方授权模块”。

从Abp接口设计上,也能看得出来两者的差别。

外部身份验证(ExternalAuthentication)关注的是校验,实现TryAuthenticateAsync并返回是否成功,而CreateUserAsync和UpdateUserAsync仅是校验流程里的一部分,不实现它并不影响身份验证结果,外部授权源的接口定义如下,

public interface IExternalAuthenticationSource<TTenant, TUser> where TTenant : AbpTenant<TUser> where TUser : AbpUserBase
{
    ...

    Task<bool> TryAuthenticateAsync(string userNameOrEmailAddress, string plainPassword, TTenant tenant);

    Task<TUser> CreateUserAsync(string userNameOrEmailAddress, TTenant tenant);

    Task UpdateUserAsync(TUser user, TTenant tenant);
}

外部授权(ExternalAuth)这一步关注的业务是拿到外部账号,如微信的OpenId,所以IExternalAuthManager重点则是GetUserInfo,而IsValidUser并没有在默认实现中使用到

public interface IExternalAuthManager
{
    Task<bool> IsValidUser(string provider, string providerKey, string providerAccessCode);

    Task<ExternalAuthUserInfo> GetUserInfo(string provider, string accessCode);
}

然而这些是从LoginManager原本实现看出的,我们可以重写这个类原本的方法,加入电话号码的处理逻辑。

在搞清楚这两个接口后,相信你会对Abp用户系统的理解更加深刻

短信获取验证码来校验,是比较常用的第三方身份验证方式,今天来做一个手机号码免密登录,并且具有绑定/解绑手机号功能的小案例,效果如图:

效果图
示例代码已经放在了GitHub上:Github:matoapp-samples

用户验证码校验模块

首先定义DomainService接口,我们将实现手机验证码的发送、验证码校验、解绑手机号、绑定手机号

这4个功能,并且定义用途以校验行为合法性,和用它来区分短信模板

定义

定义接口

public interface ICaptchaManager
{
    Task BindAsync(string token);
    Task UnbindAsync(string token);
    Task SendCaptchaAsync(long userId, string phoneNumber, string purpose);
    Task<bool> VerifyCaptchaAsync(string token, string purpose = "IDENTITY_VERIFICATION");
}

定义用途

public const string LOGIN = "LOGIN";

public const string IDENTITY_VERIFICATION = "IDENTITY_VERIFICATION";

public const string BIND_PHONENUMBER = "BIND_PHONENUMBER";

public const string UNBIND_PHONENUMBER = "UNBIND_PHONENUMBER";

定义一个验证码Token缓存管理类,以及对应的缓存条目类,用于承载验证码的校验内容

public class SmsCaptchaTokenCache : MemoryCacheBase<SmsCaptchaTokenCacheItem>, ISingletonDependency
{
    public SmsCaptchaTokenCache() : base(nameof(SmsCaptchaTokenCache))
    {
    }
}

缓存条目将存储电话号码,用户Id(非登录用途)以及用途

public class SmsCaptchaTokenCacheItem 
{
    public string PhoneNumber { get; set; }

    public long UserId { get; set; }

    public string Purpose { get; set; }
}

生成、发送验证码

阿里云和腾讯云提供了短信服务Sms,是国内比较常见的短信服务提供商,不需要自己写了,网上有大把的封装好的库,这里使用AbpBoilerplate.Sms作为短信服务库。

创建短信验证码的领域服务类SmsCaptchaManager并实现ICaptchaManager接口,同时注入短信服务ISmsService,用户管理服务UserManager,验证码Token缓存管理服务SmsCaptchaTokenCache

public class SmsCaptchaManager : DomainService, ICaptchaManager
{
    private readonly ISmsService SmsService;
    private readonly UserManager _userManager;
    private readonly SmsCaptchaTokenCache captchaTokenCache;


    public static TimeSpan TokenCacheDuration = TimeSpan.FromMinutes(5);

    public SmsCaptchaManager(ISmsService SmsService,
        UserManager userManager,
        SmsCaptchaTokenCache captchaTokenCache
        )
    {
        this.SmsService=SmsService;
        _userManager=userManager;
        this.captchaTokenCache=captchaTokenCache;

    }
}

新建SendCaptchaAsync方法,作为短信发送和缓存Token方法,CommonHelp中的GetRandomCaptchaNumber()用于生成随机6位验证码,发送完毕后,将此验证码作为缓存条目的Key值存入

public async Task SendCaptchaAsync(long userId, string phoneNumber, string purpose)
{
    var captcha = CommonHelper.GetRandomCaptchaNumber();
    var model = new SendSmsRequest();
    model.PhoneNumbers= phoneNumber;
    model.SignName="MatoApp";
    model.TemplateCode= purpose switch
    {
        CaptchaPurpose.BIND_PHONENUMBER => "SMS_255330989",
        CaptchaPurpose.UNBIND_PHONENUMBER => "SMS_255330923",
        CaptchaPurpose.LOGIN => "SMS_255330901",
        CaptchaPurpose.IDENTITY_VERIFICATION => "SMS_255330974"
    };
    model.TemplateParam= JsonConvert.SerializeObject(new { code = captcha });

    var result = await SmsService.SendSmsAsync(model);

    if (string.IsNullOrEmpty(result.BizId) && result.Code!="OK")
    {
        throw new UserFriendlyException("验证码发送失败,错误信息:"+result.Message);
    }

    await captchaTokenCache.SetAsync(captcha, new SmsCaptchaTokenCacheItem()
    {
        PhoneNumber=phoneNumber,
        UserId=userId,
        Purpose=purpose
    }, absoluteExpireTime: DateTimeOffset.Now.Add(TokenCacheDuration));
}

绑定手机号功能实现

public async Task BindAsync(string token)
{
    SmsCaptchaTokenCacheItem currentItem = await GetToken(token);
    if (currentItem==null || currentItem.Purpose!=CaptchaPurpose.BIND_PHONENUMBER)
    {
        throw new UserFriendlyException("验证码不正确或已过期");
    }

    var user = await _userManager.GetUserByIdAsync(currentItem.UserId);
    if (user.IsPhoneNumberConfirmed)
    {
        throw new UserFriendlyException("已绑定手机,请先解绑后再绑定");
    }
    user.PhoneNumber=currentItem.PhoneNumber;
    user.IsPhoneNumberConfirmed=true;
    await _userManager.UpdateAsync(user);
    await RemoveToken(token);
}

解绑手机号功能实现

public async Task UnbindAsync(string token)
{
    SmsCaptchaTokenCacheItem currentItem = await GetToken(token);
    if (currentItem==null|| currentItem.Purpose!=CaptchaPurpose.UNBIND_PHONENUMBER)
    {
        throw new UserFriendlyException("验证码不正确或已过期");
    }

    var user = await _userManager.GetUserByIdAsync(currentItem.UserId);
    user.IsPhoneNumberConfirmed=false;
    await _userManager.UpdateAsync(user);
    await RemoveToken(token);

}

验证功能实现

public async Task<bool> VerifyCaptchaAsync(string token, string purpose = CaptchaPurpose.IDENTITY_VERIFICATION)
{
    SmsCaptchaTokenCacheItem currentItem = await GetToken(token);
    if (currentItem==null || currentItem.Purpose!=purpose)
    {
        return false;
    }
    await RemoveToken(token);
    return true;
}

实际业务中可能还需要Email验证,我也建立了电子邮箱验证码的领域服务类,只不过没有实现它,动手能力强的读者可以试着完善这个小案例:)
在这里插入图片描述

接口层

AppService层创建CaptchaAppService.cs,并写好接口

public class CaptchaAppService : ApplicationService
{
    private readonly SmsCaptchaManager captchaManager;

    public CaptchaAppService(SmsCaptchaManager captchaManager)
    {
        this.captchaManager=captchaManager;
    }


    [HttpPost]
    public async Task SendAsync(SendCaptchaInput input)
    {
        await captchaManager.SendCaptchaAsync(input.UserId, input.PhoneNumber, input.Type);
    }


    [HttpPost]
    public async Task VerifyAsync(VerifyCaptchaInput input)
    {
        await captchaManager.VerifyCaptchaAsync(input.Token);
    }

    [HttpPost]
    public async Task UnbindAsync(VerifyCaptchaInput input)
    {
        await captchaManager.UnbindAsync(input.Token);

    }

    [HttpPost]
    public async Task BindAsync(VerifyCaptchaInput input)
    {
        await captchaManager.BindAsync(input.Token);

    }
}

编译并运行Web.Host项目,最终效果如下:
接口

至此我们就完成了验证码相关逻辑的接口
下一章将介绍如何重写Abp默认方法,以集成手机号登录功能。

注意!不要将本示例作为生产级代码使用
本示例中,验证码校验的接口并没有做严格加密,6位验证码也很容易被破解,因此需要考虑这些安全问题。在实际生产代码中,验证的参数常用手机号+验证码做哈希运算保证安全。

项目地址

Github:matoapp-samples

Abp.Captcha:基于ABP vNext的人机验证模块 验证码 第一阶段将提供基于ABP vNext的人机验证模块,滑杆验证和竖锯验证。 使用框架 下一个:4.0 类型:模块 演示 使用界面: API调试界面: 模块配置说明 去做 立即下载

相关推荐

Vue+abp微信扫码登录的实现代码示例

最近系统中要使用微信扫码登录,根据微信官方文档和网络搜索相关文献实现了。分享给需要的人,也作为自己的一个笔记。后端系统是基于ABP的,所以部分代码直接使用了abp的接口,直接拷贝代码编译不通过。 注册微信开放平台账号# 在微信开放平台注册,注意是开放平台不是公众平台,这里需要300元,然后申请网站应用。审核通过后获取到AppID和AppSecret以及登记的网站url。只有此url下的地址微信扫码后才能回调。 具体申请条件见官方文档。 生成登录二维码# 在vue登录页面嵌入登录二维码,根据官方文档,在页面中放入一个div元素,二维码就放在此元素中,注意var obj = new WxLo

APP上短信验证码如何验证?

方案一: 点击获取验证码–&gt;后台生成验证码,发送短信,并返回md5加密后的验证码到前端–&gt;用户输入验证码,md5加密与后台返回的md5加密验证码比较,校验。 优点:简单,便捷 缺点:用户刷新即失效,存到cookie中,也依然有丢失的风险。 方案二: 点击获取验证码–&gt;后台生成验证码,发送短信,并返存储到缓存中,如:redis...

牛奔的博客 4859

XC7K325T FPGA硬件设计实战:从板级原理图到高速接口优化

本文以XC7K325T FPGA为核心,详细阐述了从板级原理图设计到高速接口优化的完整硬件实战流程。内容涵盖芯片管脚与电源规划、时钟复位配置电路设计,并重点解析了DDR3内存子系统以及PCIe与光纤接口等高速电路的原理图与PCB设计要点,旨在帮助工程师构建稳定可靠的高性能硬件平台。

python9snake的博客 513

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

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

jevonsflash的专栏 2275

树莓派4B+WebRTC实现远程监控:5步搞定公网视频流传输(含Node.js配置)

本文详细介绍了如何利用树莓派4B和WebRTC技术,通过5个关键步骤搭建低延迟、高隐私的远程监控系统。重点阐述了WebRTC点对点传输相较于传统方案的优势,并提供了包含Node.js信令服务器配置、树莓派视频流捕获与推送、以及移动端自适应观看页面的完整实现方案,帮助用户实现公网视频流传输。

websocket5live的博客 292

HexView 脚本自动化工具:从刷写文件处理到批量转换实战

本文详细介绍了如何利用HexView脚本自动化工具高效处理嵌入式刷写文件。通过实战演示,文章展示了如何使用bat脚本实现S19、HEX等格式文件的剪切、填充、合并与批量转换,构建自动化流水线,从而显著提升汽车电子等领域的开发与生产效率。

weixin_29237635的博客 356

新建一个项目,如何使用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

告别命令行恐惧!用TBtools的MCScanX插件,5分钟搞定拟南芥和水稻的基因组共线性分析

本文介绍如何利用TBtools的MCScanX插件快速完成拟南芥和水稻的基因组共线性分析,无需命令行操作,5分钟即可生成专业可视化结果。通过图形化界面简化传统MCScanX的复杂流程,特别适合非生物信息背景的研究者,显著提升基因组数据分析效率。

dianzhuique8587的博客 377

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

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

jevonsflash的专栏 1109

离散数学期末考试试卷(两套)-熟悉题型

3.设集合A={a,b,c,d}上有自反关系R={,,,,},对称关系S={,,,}。6.设集合A={1,2,3},B={u,v,w},C={a,b,c},f是集合A到集合B上的映射,g是集合B到集合C上的映射,f={, , },g={},则复合函数g。5. 设集合A={a,b,c,d,e},下列选项中哪一个集合不是A的划分( )。

muse3159546973的博客 6956

EtherCAT丢包问题深度解析:从原理到实战排查指南

在工业自动化与运动控制领域,实时通讯网络的稳定性是系统可靠运行的基石。EtherCAT(以太网控制自动化技术)作为一种高性能工业以太网协议,其核心在于独特的“飞读飞写”机制和纳秒级的分布时钟同步,以实现多设备间的精准协同。然而,物理链路干扰、配置不当或硬件性能瓶颈都可能导致数据帧丢失,破坏时钟同步,进而引发伺服抖动、定位精度下降乃至生产线停机。本文聚焦于EtherCAT丢包这一典型故障,结合SSC(Slave Stack Code Tool)从站协议栈开发与实时系统调优等工程实践,系统阐述其成因、影响及一套

weixin_32050773的博客 341

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

接下来我们重写原Abp的部分实现,来驳接手机号相关业务。

jevonsflash的专栏 1587

Redhawk: 为什么STA CHECK中switch cell覆盖率为0(STA file中switch control pin没有timing window)?

如题,做dynamic analysis时,不需要switch cell的timing window信息,但是做low power analysis需要做上电时switch cell的timing window就是必须的了,本文对switch cell control pin没有timing window (STA CHECK覆盖率为零)的这种现象做分析。

m0_61544122的博客 1197

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

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

jevonsflash的专栏 714

手把手教你学Simulink--电动物流车预充电路控制及主继电器粘连检测电机负载仿真

摘要:本文基于Simulink仿真平台,研究了电动物流车预充电路控制策略及主继电器粘连检测技术。通过构建预充电路、主继电器检测及电机负载模型,分析了不同工况下的系统特性。研究表明,优化的预充控制策略可缩短预充时间至0.5秒内,降低电流峰值;主继电器粘连检测模型能准确识别故障;电机负载变化对系统性能具有显著影响。仿真结果验证了所提方法的有效性,为提升电动物流车安全性与可靠性提供了理论支持和技术参考。

MHD0815的博客 62

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

abp中多种登陆用户的设计

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

zhoumouren88的博客 1633

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Abp vnext 授权(Authorization)

文章目录介绍授权属性权限系统定义权限本地化权限名称多租户启用/禁用权限子权限通过自定义策略覆盖权限更改从属模块的权限定义IAuthorizationService在JavaScript中检查权限MVC用户界面Angular UI权限管理高级主题权限值提供程序权限存储AlwaysAllowAuthorizationService也可以看看 介绍 授权用于检查是否允许用户在应用程序中执行某些特定操作。 ABP通过将权限添加为自动策略来扩展ASP.NET Core授权,并允许授权系统也可在应用程序服务中使用。 因

寒冰屋的专栏 7833

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

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

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

jevonsflash的专栏 2222

用Abp实现两步验证(Two-Factor Authentication,2FA)登录(二):Vue网页端开发

前端代码的框架采用vue.js + elementUI 这套较为简单的方式实现,以及typescript语法更方便阅读。首先添加全局对象:loginForm: 登录表单对象twoFactorData: 两步验证数据,showTwoFactorSuccess: 是否显示两步验证成功提示。

jevonsflash的专栏 6466

ABP vNext 拓展短信授权登陆

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

神奇海螺 2177

abp框架注册后登陆

[Route("api/[controller]/[action]")] [ApiController] public class WeChatController : ControllerBase { private readonly RepositoryWeChatThepublic _repositoryWeChat; private readonly TokenAuthController _token; private re.

你要明白,任何问题都不是孤立存在的,一定有人曾经遇到过,并且已经有更好的解决办法了,只是我还不知道。我不应该在黑暗中独自前行,去重新发明轮子,也许我的顿悟,只是别人的基本功!我应该要站在巨人的肩膀上,学习更成熟的经验和方法,然后再来解决这个问题 1888

AbpVnext 扩展企业微信扫码登录(钉钉登陆、短信登陆、微信登陆等)Vue框架

abp vnext - ABP框架 - 开源Web应用程序框架!ABP 是一个开源应用程序框架,专注于基于 AspNet Core 的 Web 应用程序开发。 Don't repeat yourself,专注于自己的业务代码。

m0_72992974的博客 2424

Asp.net core abp 无密码登录

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

Martin 的博客 1086

salt之external auth

因为线上生产不可能都要以root权限去操作软件,需要其他用户权限来操作salt本例以test用户为例:useradd testpasswd test(test)vim /etc/salt/masterexternal_auth: <<<< enable external authentication pam: ...

weixin_34082695的博客 304

Abp 微信小程序登录 基本的流程和实践

需求:有个web端,然后移动端使用微信小程序。要把微信用户和系统中的用户对应起来 上一篇搞了个钉钉小程序登录:钉钉小程序登录 微信小程序登录,方便用户输入和系统中校验的也就只有手机号了,既能保证用户唯一标识,也能和系统中的用户关联起来。 数据库表: AbpUser表中的PhoneNumber就是这个Providerkey 首先 微信小程序-> wx.login -> 获取到code -> 后端用code 去拿用户openid和session_key ->...

Martin 的博客 2316
上一篇: 适用于AbpBoilerplate的阿里云腾讯云Sms短信服务
下一篇: 用Abp实现短信验证码免密登录(二):改造Abp默认实现
林晓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、付费专栏及课程。

余额充值