转载自:https://www.nbucedog.com/blog/article/6
如果将用户的密码以明文的方式直接保存在数据库中是非常不安全的,因为数据库一旦被bad guys黑掉了,那些bad guys就可以通过盗走的数据了解到用户们的常用密码,用这些密码去尝试登录其他网站。所以密码一般要经过一些不可逆算法再存储到数据库以提高安全性,这样,就算数据库被盗,bad guys也不知道真实的密码是什么。 我们称这样的算法为哈希算法,同时要注意哈希算法并不是加密算法。加密的英文单词是encrypt,而我们注册时用的是encode;解密的单词是decrypt,而我们登录时用的是match。也就是说我们的注册和登录这个过程是“编码/匹配”的过程,而不是“加密/解密”。我们接下来看一下具体的使用过程。
1.首先是在WebSecurityConfigurerAdapter里重写configure(参数要求如下面代码)方法
@Override protected void configure(AuthenticationManagerBuilder auth)throws Exception{ auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder()); }可以看到这个方法就是在表明具体采用的编码/匹配方式是BCryptPasswordEncoder。所以,要想设置别的编码/匹配方式也可以,在这里把BCryptPasswordEncoder改成别的编码/匹配方式就可以了。也可以自己写一个编码/匹配方式,只要继承了PasswordEncoder这个接口就可以了,比如说我们不想整这些花里胡哨的,就想实现明文的密码匹配,那可以像下面这样写,然后再在刚才的地方调用它
//引入这个接口 import org.springframework.security.crypto.password.PasswordEncoder; public class MyPasswordEncoder implements PasswordEncoder{ //实现编码方法 public String encode(CharSequence charSequence) { return charSequence.toString(); } //实现匹配方法 public boolean matches(CharSequence charSequence, String s) { return s.equals(charSequence.toString()); } }2.接下来是注册的地方需要将用户提交的密码进行编码就可以了
String encode = new BCryptPasswordEncoder().encode(request.getParameter("password")); user.setPassword(encode);细心的程序员(我没说是我)会发现,即使密码是同一个,每次调用encode(密码)方法后的结果都不一样,但它的确每次都能匹配成功,这是为什么呢?而且一般的哈希算法都需要一个“盐”值来生成结果,并且需要将这个盐值保存在数据库中,之后还需要这个盐值去做密码的匹配。但BCryptPasswordEncoder似乎并不需要颜值盐值,这又是为什么呢? 原来,encode(密码)方法已经将盐值加在输出后字符串里了。
