- 前言
- 解决过程
- 解决
- 总结
前言 前面基础的登录,权限验证等都已经完成了,现在想实现记住密码的操作,按网上博客来实现了一翻,却总是失败,token并没有存储到persistent_logins表。
解决过程
经过调试发现是因为当登录成功的时候,rememberMeServices执行的方法是NullRememberMeServices下面的:
可以看到它执行了NullRememberMeServices下面的方法。
然后查看另外一个实现类下面的代码AbstractRememberMeServices,可以看到它下面是有把token存储到数据库的流程的。并且,网上的一些教程,上面放出的代码,也是跑的AbstractRememberMeServices下面的。
下面是源码:
因为我们要把token存储到数据库,所以,选第一个实现类PersistentTokenbasedRememberMeServices
下面就是存储的代码了
所以,接下来,就该想办法怎么跑这个实现类了。
解决重写successfulAuthentication方法
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
PersistentTokenbasedRememberMeServices rememberMe = new PersistentTokenbasedRememberMeServices("KEY", myUserDetailService, persistentTokenRepository);
// 重新设置remember-me参数key
rememberMe.setParameter("rememberMe");
// 重新设置rememberMeServices实现类
this.setRememberMeServices(rememberMe);
super.successfulAuthentication(request, response, chain, authResult);
}
这里面有2个点。
-
当前这个方法是重写在哪个类下面
我这个因为是前后端分离的,所以重写了这个过滤器。里面有重写了attemptAuthentication方法,对json做了处理。
-
方法里面的参数有哪些,怎么来的
主要是这行代码:
key,目前还不知道有什么用,因为还没做到这块;
myUserDetailService,就是登陆用的service,这个应该都有的;
persistentTokenRepository,存储token的一个bean,代码放在下面,这个百度也可以搜到的。PersistentTokenbasedRememberMeServices rememberMe = new PersistentTokenbasedRememberMeServices("KEY", myUserDetailService, persistentTokenRepository)persistentTokenRepository代码
@Bean public PersistentTokenRepository persistentTokenRepository() { JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl(); jdbcTokenRepository.setDataSource(dataSource); jdbcTokenRepository.setCreateTableOnStartup(false); return jdbcTokenRepository; }
就这些了,这些都是在已经实现了登录的基础上加的。
后面还有个问题,就是这理虽然已经重写设置了rememberMe(默认是remember-me,通过调试源码可以看到),但是因为里面通过request.getParameter获取的,所以里面获取不到。
截图:
如果想要临时通过验证,测试存储token到数据库的效果,那么可以先把this.alwaysRemember设置为true,然后子再进行测试。
验证通过,存储token
request获取不到rememberMe的问题:
转载自:https://blog.csdn.net/liukangjie520/article/details/111617244
其实和上面的处理思路一样,也是继承类,重写一下就成了。
public class MyPersistentTokenbasedRememberMeServices extends PersistentTokenbasedRememberMeServices {
private boolean alwaysRemember;
@Override
public void setAlwaysRemember(boolean alwaysRemember) {
this.alwaysRemember = alwaysRemember;
}
@Override
protected boolean rememberMeRequested(HttpServletRequest request, String parameter) {
if (alwaysRemember) {
return true;
}
// 判断请求是否为JSON
if (request != null
&& request.getMethod().equalsIgnoreCase("POST")
&& request.getContentType() != null
&& (request.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE) || request.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE))
) {
Boolean rememberMe = (Boolean) request.getAttribute("rememberMe");
if (rememberMe) {
return true;
}
}
// 否则调用原本的自我记住功能
return super.rememberMeRequested(request, parameter);
}
public MyPersistentTokenbasedRememberMeServices(String key, UserDetailsService userDetailsService, PersistentTokenRepository jdbcTokenRepositoryImpl) {
super(key, userDetailsService, jdbcTokenRepositoryImpl);
}
}



