(一个做认证平台,必须会遇到的一个问题)
BCVP框架,是基于:
ASP.NETCore5.0+VUE.js+IdentityServer4等核心技术,实现的前后端分离与动态认证鉴权一体化平台。
无论你是自己做开源项目,抑或是自己公司的项目,只要是一套完整的、闭环的、成型的框架,肯定会有授权认证,那也就肯定会有用户模块,登录部分必不可少,那找回密码也是与之相生的影子——有登录,肯定有找回。
在BCVP框架中,用到了IdentityServer4(下文统称Ids4)作为认证平台中心,丰富的API为我们管理认证、客户端、用户、资源、令牌等复杂逻辑提供了可能。开源这么久了,一直没有机会去处理密码找回这个需求,官方当然也提供了各种扩展方法,但是这些扩展都不是最重要的,那找回密码什么是最重要的呢?——答案就是服务器和客户端的通讯。
常见的密码找回很简单,要么发短信,要么发邮件,只有这样才能保证信息的安全和稳定性,但是我毕竟没有这些额外的付费服务。
当然还有其他的办法,就是使用类似对接QQ、微信、GitHub、Google这种第三方认证平台做个二次登录,来保证唯一性,把密码找回转嫁到第三方平台上,这种方案我个人感觉不太喜欢,既然自己已经做认证平台了,再对接一个认证平台,总感觉怪怪的。所以平时就通过Github上,提issue,我手动做的密码重置,就是文章开篇的那张图所示。
但是这样毕竟不是长久之计,肯定需要一种方案,既可以不使用第三方的通讯工具,更可以让用户自己来更新和找回密码,我思考了下,趁着周末在家没有很忙,好好的思考了下,采用密保问题的形式,来让用户自己在线更新或找回密码。同时也更新一波代码,让自己对代码和架构的感觉不要停下来。
本文所涵盖的技术都很简单,写的目的,就是想顺着思路,提供一种框架设计的思想。
还在之前的登录信息中,增加了两个密码问题,目前都是必填项。
在源代码中,因为用的ORM是EFCore,相关的迁移已经做好了,更新最新代码,然后执行update-database即可,当然,直接更新你的数据库也可:
(注意要指定上下文)
(在用户表中添加)
从这一版本开始,注册用户开始需要密保问题了,之前的肯定没有,所以之前的用户如果找密码,就还是用之前的issue里给我留言吧,当然,我下一版本会增加修改个人信息的功能,到时候之前没有设置密保的,可以增加上密保问题,为以后丢失密码做准备,这也是一种框架设计方案。
还这样注册完成后,我们就可以尝试下,找回密码好不好用?
PS: 这种方案以后,目前超级管理员就暂时不能修改别人的密码了,所以我先试水一段时间,尽量让用户自己重置密码,管理员还是不要轻易的重置用户密码了,后期有需要也可以再加上。
首先在登录页面,点击密码重置
(登录输入自己邮箱,或未登录输入正确密保答案)
(未登录,也未输入密保问题)
(未登录,输入了密保,但是该邮箱下,密保不正确)
这样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 exist
return RedirectToAction(nameof(ResetPasswordConfirmation));
}
else
{
if (user.Id.ToString() != model.userId)
{
return RedirectToAction(nameof(AccessDenied),
new { errorMsg = "不能修改他人邮箱!密码重置失败!" });
}
}
_userManager.Users.FirstOrDefault(d =>
(d.LoginName == model.Username || d.Email == model.Username) && !d.tdIsDelete);
好啦,本次认证中心更新完成啦,不借助任何第三方来实现在线找回密码已经完成,如果对你有帮助点赞👍哟。
如果有任何技术问题,欢迎下边留言吧👇。