讲到密码加密这一点,我们应该很容易接受,我们存在数据库中的密码不可能是明文方式,以前我们都是使用md5这样的算法来加密密码或者使用sha的方式来加密,现在它们都被新宠BCryptPasswordEncoder夺取了光彩。
我们在使用加密的密码时,其实使用方式很简单,配置也很简单。先看一下我们的使用方式
就是很简单地调用了encode(),由于我们没有之间写登录的实现,所以我们没有一个直接的密码比较的过程。相反我们只需要做好配置就行了。
配置就是注入一个Bean,同时我们看到了在authProvider()我们使用到了encoder(),有了它们spring-security就“自动”完成登录验证。
上面的配置和使用,都是比较简单的,然后让我们回到“重置密码”。
先梳理一下重置密码的流程:
- 登录页面,用户点击“重置密码”按钮 ;
- 跳转到重置密码页面 ;
- 用户输入email地址,再点击“重置”按钮 ;
- 后台发送邮件给用户,生成重置密码链接 ;
- 用户收到邮件后点击链接,跳转到重置密码,输入新密码,提交 ;
- 后台处理,完成密码重置的过程。
对于用户的交互的流程是1、3、5;其余是都是程序处理。对于整个流程而言是有点长,但还是可以接受。我们写代码的思路也就清醒起来。
首先是忘记密码页面forgetPassword.html,一个输入框和一个重置按钮,比较简单。
然后就是重置按钮提交给后台的处理:
我们仍然采用事件机制,发布一个重置密码事件。
重置密码事件的处理也很简单就是发送邮件:
然后用户邮箱应该受到这样一封邮件
当用户点击上面的链接应该跳转到修改密码页面
上面使用到了SecurityContextHolder这个工具类,设置了Authentication,这是因为后面处理保存密码的时候需要使用用户信息。
最后填写好新密码及确认密码后提交给后台处理
用户密码更新完成后再次跳转到登录页面,然后使用新密码就可以登录了。
至此,我们完成了重置密码的所有编码工作。最后让我看下一共修改了哪些文件。
①IUserService中共添加4个接口
②MvcConfig中添加了2行
③OldRegistrationController添加了3个接口
④WebSecurityConfig中添加了3个放行url
⑤java文件中新增了实体类PasswordResetToken和相应的Repo,还有OnResetPasswordEvent和ResetPasswordListener
html文件中新增了forgetPassword.html和updatePassword.html
小结:总体上,完成密码重置的编码工作不是很复杂,只要上面的流程清晰,加上用到了前面java mail,spring事件处理,还有spring security中的一个工具类SecurityContextHolder和UsernamePasswordAuthenticationToken,它们完成了请求上下文中认证信息的传递。
具体的代码可以参见github.