【Blog.Idp开源】支持在线密码找回

(一个做认证平台,必须会遇到的一个问题)

BCVP框架,是基于:

ASP.NETCore5.0+VUE.js+IdentityServer4等核心技术,实现的前后端分离与动态认证鉴权一体化平台。

01

密码找回

认证中心绕不开的话题

Architecture Design.

无论你是自己做开源项目,抑或是自己公司的项目,只要是一套完整的、闭环的、成型的框架,肯定会有授权认证,那也就肯定会有用户模块,登录部分必不可少,那找回密码也是与之相生的影子——有登录,肯定有找回。

在BCVP框架中,用到了IdentityServer4(下文统称Ids4)作为认证平台中心,丰富的API为我们管理认证、客户端、用户、资源、令牌等复杂逻辑提供了可能。开源这么久了,一直没有机会去处理密码找回这个需求,官方当然也提供了各种扩展方法,但是这些扩展都不是最重要的,那找回密码什么是最重要的呢?——答案就是服务器和客户端的通讯

常见的密码找回很简单,要么发短信,要么发邮件,只有这样才能保证信息的安全和稳定性,但是我毕竟没有这些额外的付费服务。

当然还有其他的办法,就是使用类似对接QQ、微信、GitHub、Google这种第三方认证平台做个二次登录,来保证唯一性,把密码找回转嫁到第三方平台上,这种方案我个人感觉不太喜欢,既然自己已经做认证平台了,再对接一个认证平台,总感觉怪怪的。所以平时就通过Github上,提issue,我手动做的密码重置,就是文章开篇的那张图所示。

但是这样毕竟不是长久之计,肯定需要一种方案,既可以不使用第三方的通讯工具,更可以让用户自己来更新和找回密码,我思考了下,趁着周末在家没有很忙,好好的思考了下,采用密保问题的形式,来让用户自己在线更新或找回密码。同时也更新一波代码,让自己对代码和架构的感觉不要停下来。

本文所涵盖的技术都很简单,写的目的,就是想顺着思路,提供一种框架设计的思想。

02

新注册增加密保问题

手动输入,保证内容灵活可变

Create a new account.

还在之前的登录信息中,增加了两个密码问题,目前都是必填项。

在源代码中,因为用的ORM是EFCore,相关的迁移已经做好了,更新最新代码,然后执行update-database即可,当然,直接更新你的数据库也可:

(注意要指定上下文)

(在用户表中添加)

从这一版本开始,注册用户开始需要密保问题了,之前的肯定没有,所以之前的用户如果找密码,就还是用之前的issue里给我留言吧,当然,我下一版本会增加修改个人信息的功能,到时候之前没有设置密保的,可以增加上密保问题,为以后丢失密码做准备,这也是一种框架设计方案。

还这样注册完成后,我们就可以尝试下,找回密码好不好用?

PS: 这种方案以后,目前超级管理员就暂时不能修改别人的密码了,所以我先试水一段时间,尽量让用户自己重置密码,管理员还是不要轻易的重置用户密码了,后期有需要也可以再加上。

03

忘记?找回密码

Forgot your password?

首先在登录页面,点击密码重置

这里的重置包括两个场景:1、未登录的找回,2、登录状态的修改。

然后填写邮箱和之前填写的密保问题,考虑到之前的老用户,是没有设置密保的,所以这里是选填项,如果点击提交,会出现三种情况:

1、如果是管理员,或者是登录状态,可以更新操作;

2、如果未登录,但是有密保问题,也可以更新操作;

3、其他的,返回错误;

(登录输入自己邮箱,或未登录输入正确密保答案)

(未登录,也未输入密保问题)

(未登录,输入了密保,但是该邮箱下,密保不正确)

如果邮箱和密保问题都正确,那就可以得到更新密码的连接,更新自己的密码。

这样看起来我们已经完美的解决了重置密码的问题,但是却不是这样的,请继续往下看。

04

篡改他人的重置地址

增加参数戳

AccessCode.

因为这个重置密码的链接,每个人都能拿到,拿到后手动更改其中的参数,或者研究了规则,也可以故意修改别人的邮箱(比如知道了张三的uiserId和Email,就可以更新他的密码了),url是这样的:

https://ids.neters.club/account/reset-password?userId=4045&code=CfDJ8HGMaC81CCVNj8gqKOrlZ5tFOx03UOdLeRYDQA8ktHq6cojFCMVS85P6iy0LkRa1GmeV9QzXbzwmowy1NQHPUBfKYBEVmP7BSleaPZCQv%2BQGVFCRhfPPvvlcMVDuKfpvJbbKE%2B8LsHjn%2Fkm2A%2F2BrMM%2FzuZfypjHqlMD%2F%2BgAHwWQqwx9Eq77%2BFpEauVUE7D1Fw%3D%3D

这种肯定是不行的,所以需要对url进行加密,防止篡改,那我就又想了一下,增加了一个随机参数accessCode,把userId和Code进行md5加密,就算知道userId和Email,也无法知道code和accessCode。因为code是user对象转出来的,而且这个code也是有一定的有效期的,就比如下边这个链接的code是无效的,那更别提重置密码了,所以安全性是可以的。

https://ids.neters.club/account/reset-password?userId=4045&code=CfDJ8HGMaC81CCVNj8gqKOrlZ5tFOx03UOdLeRYDQA8ktHq6cojFCMVS85P6iy0LkRa1GmeV9QzXbzwmowy1NQHPUBfKYBEVmP7BSleaPZCQv%2BQGVFCRhfPPvvlcMVDuKfpvJbbKE%2B8LsHjn%2Fkm2A%2F2BrMM%2FzuZfypjHqlMD%2F%2BgAHwWQqwx9Eq77%2BFpEauVUE7D1Fw%3D%3D&accessCode=60F15185E53181B775809F9B24B8C5AE

这样url就保证不会被篡改,那更新的只能是当前userId

// 防止篡改
var getAccessCode = MD5Helper.MD5Encrypt32(model.userId + model.Code);
if (getAccessCode != model.AccessCode)
{return RedirectToAction(nameof(AccessDenied), new { errorMsg = "随机码已被篡改!密码重置失败!" });
}

并且是当前userId的Email,不能是其他人的Email

var user = await _userManager.FindByEmailAsync(model.Email);
if (user == null)
{// Don't reveal that the user does not existreturn RedirectToAction(nameof(ResetPasswordConfirmation));
}
else
{if (user.Id.ToString() != model.userId){return RedirectToAction(nameof(AccessDenied), new { errorMsg = "不能修改他人邮箱!密码重置失败!" });}
}

05

支持邮箱登录

更多策略

UserName & Email.

因很多小伙伴也反馈一个问题,就是老是记不得自己的登录名,倒是能记得自己的邮箱,所以本次也正好更新下登录方式,很简单:

_userManager.Users.FirstOrDefault(d => (d.LoginName == model.Username || d.Email == model.Username) && !d.tdIsDelete);

好啦,本次认证中心更新完成啦,不借助任何第三方来实现在线找回密码已经完成,如果对你有帮助点赞????哟。

如果有任何技术问题,欢迎下边留言吧????。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/299696.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我的狗丢了,所以我能加你微信吗? | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅(图源网络,侵权删)

Yahoo网站性能最佳体验的34条黄金守则

Yahoo!的Exceptional Performance团队为改善Web性能带来最佳实践。他们为此进行了一系列的实验、开发了各种工具、写了大量的文章和博客并在各种会议上参与探讨。最佳实践的核心就是旨在提高网站性能。 Excetional Performance团队总结出了一系列可以提高网站速度的方法。可以分…

hdu 4597 + uva 10891(一类区间dp)

题目链接:http://vjudge.net/problem/viewProblem.action?id19461 思路:一类经典的博弈类区间dp,我们令dp[l][r]表示玩家A从区间[l, r]得到的最大值,于是就有dp[l][r] sum[l][r] - min(dp[l i][r], dp[l][r - i]) (i > 1 && i …

将VC++6.0的代码迁移到VS2005常见问题总结(Window核心编程第五版以前代码在VS2005无法编译的解决方案)...

额喜新厌旧是男人的通病吧,可是呢VS2005的界面看着的确比VC6.0看着舒服,而且也算用习惯了吧。可是网上现在大部分C/C的代码还是用VC6.0的。这为我们这些菜鸟的学习之路增添了不少障碍,可能有很多朋友在这一步就放弃了吧或者抹黑走下去&#x…

被问到了!为什么一定要使用分布式,内行啊

一、为什么要使用分布式 如果需求要测试 4000 虚拟用户数,而本机只能支持1000 虚拟用户,如果测试结果有可能是电脑的问题,而不是服务器的问题,所以需要把其他虚拟用户分配到多台电脑上 把虚拟用户数分配到其他电脑上面去执行&am…

设计模式之享元

享元模式介绍享元模式主要在于共享通用对象,减少内存的使用,提升系统的访问效率。而这部分共享对象通常比较耗费内存或者需要查询大量接口或者使用数据库资源,因此统一抽离作为共享对象使用。在使用此模式过程中,需要使用享元工厂…

真正拉开人与人之间的差距是什么?

全世界只有3.14 % 的人关注了青少年数学之旅身边总有些人看上去很轻松,不仅在工作中游刃有余,还知识渊博,对各种事情有自己的思考。这样的人一定是天生的学霸吧。其实学习不一定要在教室里从一本书的第一页开始看,学习可以很轻松。…

ORACLE备份中的压缩

默认的情况下,如果没有配置压缩备份,或者备份的时候没有发出compressed 命令,那么ORACLE会采用NULL数据块的压缩方法来备份数据库,采用这种方法备份,ORACLE就不会备份从未使用过的数据块。另外一种备份就是采用compres…

[导入]【翻译】WF从入门到精通(第八章):调用外部方法及工作流

摘要: 学习完本章,你将掌握: 1.创建并调用你的工作流外部的本地数据服务 2.理解怎样使用接口来为宿主进程和你的工作流之间进行通信。 3.使用设计的外部方法在你的工作流和宿主应用程序之间传输数据。 4.在一个正执行的工作流中调用其它工作流 阅读全文…

(译)Windsor入门教程---第三部分 编写第一个Installer

原文:http://docs.castleproject.org/Windsor.Windsor-tutorial-ASP-NET-MVC-3-application-To-be-Seen.ashx 简介 在第二部分我们创建了控制器工厂。现在我们要把我们的控制器交给Windsor来管理。 Installer Windsor有一个专门的类installer.cs,用来向容…

在 ASP.NET Core 中使用 Serilog 使用 Fluentd 将日志写入 Elasticsearch

在 ASP.NET Core 中使用 Serilog 使用 Fluentd 将日志写入 Elasticsearch原文来自:https://andrewlock.net/writing-logs-to-elasticsearch-with-fluentd-using-serilog-in-asp-net-core/对于在 Kubernetes 中运行的应用程序,将日志消息存储在一个中心位…

2021年度最全面JVM虚拟机,类加载过程与类加载器

前言 类装载器子系统是JVM中非常重要的部分,是学习JVM绕不开的一关。 一般来说,Java 类的虚拟机使用 Java 方式如下: Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class …

做生意最重要的诚信呢??? | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅(图源网络,侵权删)

从笑话中看到产品创意

西贝在公司的洗手间中看到了2则笑话,体会出来笑话的另一个含义,其实它和产品有很多相似之处的。第一则:某学校的小师妹看上了校中的师兄帅哥,决定主动追求。小师妹遇上之后主动搭讪“师兄,有女朋友吗?”帅哥…

快速配置Ehcache

1. 编写ehcache.xml文件&#xff0c;将该文件放置于classpath路径下。代码如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?><ehcache> <!-- 缓存文件生成之后所放置的路径 --> <diskStore path"D:/Develop/tomcat-6…

.NET 6 预览版 7 发布--(最后一个预览版)

原文&#xff1a;bit.ly/2VJxjxQ作者&#xff1a;Richard翻译&#xff1a;精致码农-王亮说明&#xff1a;文中有大量的超链接&#xff0c;这些链接在公众号文章中被自动剔除&#xff0c;一部分包含超链接列表的小段落被我删减了&#xff0c;如果你对此感兴趣&#xff0c;请参考…

面试避坑手册之 Java字节流和字符流总结IO流!

从接收输入值说起 在日常的开发应用中&#xff0c;有时候需要直接接收外部设备如键盘等的输入值&#xff0c;而对于这种数据的接收方式&#xff0c;我们一般有三种方法&#xff1a;字节流读取&#xff0c;字符流读取&#xff0c;Scanner 工具类读取。 字节流读取 直接看一个…

这家AI公司用面具破解中国人脸识别系统!微信、支付宝、火车站无一幸免

全世界只有3.14 % 的人关注了青少年数学之旅据外媒报道&#xff0c;一家人工智能公司Kneron用一个特制的3D面具&#xff0c;成功欺骗了包括支付宝和微信在内的诸多人脸识别支付系统&#xff0c;完成了购物支付程序。他们用同样的方式甚至进入了中国的火车站。现如今&#xff0c…

coolite TreeNode NodeClick传id到后台的方法

重点如下&#xff1a; 1 <AjaxEvents>2 <Click OnEvent"PanelTree_Click" >3 <EventMask ShowMask"true" Msg"正在执行,请稍后" />4 <E…

使silverlight适应IE窗口大小的方法

Pete Brown在它的BLOG中提到了一个按自定义比例使用silverlight适应IE窗口大小的方法 原文如下&#xff1a;How to Resize a Silverlight 2 App and Keep the Same Aspect Ratio 其核心代码如下&#xff08;Xaml&#xff09;&#xff1a; <UserCon…