Spring Boot图书管理系统项目实战-3.用户登录
导航:
pre: 2.项目搭建
next:4.基础信息管理
只挑重点的讲,具体的请看项目源码。
1.项目源码
2.登录页设计
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="/static/layui/css/layui.css" th:href="@{/static/layui/css/layui.css}">
<link rel="stylesheet" href="/static/css/admin.css" th:href="@{/static/css/admin.css}">
<link rel="stylesheet" href="/static/css/login.css" th:href="@{/static/css/login.css}">
<link id="layuicss-layer" rel="stylesheet" href="/static/css/layer.css" th:href="@{/static/css/layer.css}">
</head>
<body>
<div class="layadmin-user-login layadmin-user-display-show" id="LAY-user-login" style="display: none;">
<div class="layadmin-user-login-main">
<div class="layadmin-user-login-box layadmin-user-login-header">
<h2>Bookman</h2>
<p>图书管理系统</p>
</div>
<form class="layadmin-user-login-box layadmin-user-login-body layui-form" th:action="@{/login}" method="post">
<div class="layui-form-item">
<label class="layadmin-user-login-icon layui-icon layui-icon-username" for="username"></label>
<input type="text" name="username" id="username" lay-verify="required" placeholder="用户名" class="layui-input">
</div>
<div class="layui-form-item">
<label class="layadmin-user-login-icon layui-icon layui-icon-password" for="password"></label>
<input type="password" name="password" id="password" lay-verify="required" placeholder="密码" class="layui-input">
</div>
<div class="layui-form-item">
<button class="layui-btn layui-btn-fluid" type="submit" lay-submit="" lay-filter="LAY-user-login-submit">登 入</button>
</div>
<div class="layui-form-item" th:if="${param.error}">
用户名或密码错误!
</div>
</form>
</div>
<div class="layui-trans layadmin-user-login-footer">
<p>© 2020 <a href="http://www.layui.com/" target="_blank">laoxu.com</a></p>
</div>
</div>
<script src="/static/js/jquery-1.11.3.min.js" th:src="@{/static/js/jquery-1.11.3.min.js}"></script>
<script src="/static/layui/layui.js" th:src="@{/static/layui/layui.js}"></script>
</body>
</html>
3.spring security配置类
/**
* Spring Security配置
*
* @author laoxu
* @create 2018-10-26
**/
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
/* @Autowired
private DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource);
}*/
@Autowired
MyAuthenctiationSuccessHandler myAuthenctiationSuccessHandler;
@Resource
private DataSource dataSource;
@Resource(name = "userDetailServiceImpl")
private UserDetailServiceImpl<User> userService;
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
// 配置数据源
jdbcTokenRepository.setDataSource(dataSource);
// 第一次启动的时候自动建表(可以不用这句话,自己手动建表,源码中有语句的)
// jdbcTokenRepository.setCreateTableOnStartup(true);
return jdbcTokenRepository;
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(new MyPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/book/list").permitAll()
.antMatchers("/bookDetail/*").permitAll()
.anyRequest().authenticated()
.and().formLogin().loginPage("/login").permitAll().successHandler(myAuthenctiationSuccessHandler)
.and().logout().permitAll()
.and().headers().frameOptions().disable()
;
//开启记住我功能
//http.rememberMe().tokenRepository(persistentTokenRepository()).userDetailsService(userService).tokenValiditySeconds(86400);
//http.rememberMe().rememberMeParameter("remember-me").key("laoxu").tokenValiditySeconds(86400);
http.csrf().disable();
}
@Override
public void configure(WebSecurity web) throws Exception {
//忽略
web.ignoring().antMatchers("/static/**");
web.ignoring().antMatchers("/","/index");
}
}
4.登录成功处理器
/**
* @Description: 自定义登录成功处理类
* @Author laoxu
* @Date 2019/5/25 23:32
**/
@Component
public class MyAuthenctiationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Autowired
UserService userService;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
response.setContentType("application/json;charset=utf-8");
RequestCache cache = new HttpSessionRequestCache();
SavedRequest savedRequest = cache.getRequest(request, response);
// 如果来源请求为空则跳转到管理后台
String url = "admin";
/*if((savedRequest==null)){
url = "admin";
}else{
url = savedRequest.getRedirectUrl();
}*/
// 获取登录用户详细信息
User user = userService.getUserByUsername(SecurityUtil.getLoginUser());
request.getSession().setAttribute("loginUser",user);
// 返回jwt
response.sendRedirect(url);
}
}
5.自定义UserService实现
@Service
public class UserDetailServiceImpl<T extends User> implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
try {
User user = userService.getUserByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("用户:"+username+"不存在!");
}
//用户权限
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
/*if (StringUtils.isNotBlank(user.getRoles())) {
String[] roles = user.getRoles().split(",");
for (String role : roles) {
if (StringUtils.isNotBlank(role)) {
authorities.add(new SimpleGrantedAuthority(role.trim()));
}
}
}*/
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}