思维导图:
项目源码已上传至码云:
https://gitee.com/Huke-123/cms_system
创建一个util包,用于放我们自己实现的工具类;
Md5Util类:
package com.cms.util;
import org.apache.shiro.crypto.hash.Md5Hash;
public class Md5Util {
//命名盐的方式
public static final String SALT="java";
/**
* Md5加密
* @param str
* @param salt
* @return
*/
public static String md5(String str,String salt){
return new Md5Hash(str,salt).toString();
}
public static void main(String[] args) {
String password="123";
System.out.println("Md5加密后:"+ Md5Util.md5(password, Md5Util.SALT));
}
}
加密后可以测试一下:
注意此时要把数据库里面的明文密码换成输出的密文!
MyRealm类:
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//通过token获取用户名
String userName=(String) token.getPrincipal();
//通过用户名查找用户,返回一个实体
Manager manager=managerService.getByUserName(userName);
//与页面的实体进行比较
if(manager!=null){
SecurityUtils.getSubject().getSession().setAttribute("currentUser", manager);
AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(manager.getUserName(), manager.getPassword(), "xxx");
return authcInfo;
}else{
return null;
}
}
在这之前,我们需要写一个通过用户名查找用户的方法;先在ManagerDao接口内:
package com.cms.dao;
import com.cms.entity.Manager;
/**
* 管理员Dao接口
* @author user
*
*/
public interface ManagerDao {
/**
* 通过用户名查询用户
* @param userName
* @return
*/
public Manager getByUserName(String userName);
}
然后是映射文件ManagerMapper.xml:
<select id="getByUserName" parameterType="String" resultMap="ManagerResult">
select * from t_manager where userName=#{userName}
</select>
还有service层里面的文件ManagerService接口:
package com.cms.service;
import com.cms.entity.Manager;
/**
* 管理员Service接口
* @author user
*
*/
public interface ManagerService {
/**
* 通过用户名查询用户
* @param userName
* @return
*/
public Manager getByUserName(String userName);
}
以及ManagerServiceImpl类:
package com.cms.service.impl;
import javax.annotation.Resource;
import com.cms.entity.Manager;
import org.springframework.stereotype.Service;
import com.cms.dao.ManagerDao;
import com.cms.service.ManagerService;
/**
* 管理员Service实现类
* @author user
*
*/
@Service("managerService")
public class ManagerServiceImpl implements ManagerService{
@Resource
private ManagerDao managerDao;
/**
* 通过用户名查询用户
* @param userName
* @return
*/
public Manager getByUserName(String userName){
return managerDao.getByUserName(userName);
}
}
我们在ManagerController类里面:
/**
* 用户登录
* @param manager
* @param response
* @return
* @throws Exception
*/
@RequestMapping("/login")
public String login(Manager manager, HttpServletResponse response)throws Exception{
//获取认证主体
Subject subject= SecurityUtils.getSubject();
//封装token信息,用户名和密码
UsernamePasswordToken token=new UsernamePasswordToken(manager.getUserName(), Md5Util.md5(manager.getPassword(), Md5Util.SALT));
JSONObject result=new JSONObject();
try{
//主体登录,进行token比较
subject.login(token);
result.put("success", true);
}catch(Exception e){
result.put("success", false);
result.put("errorInfo", "用户名或者密码错误!");
e.printStackTrace();
}
//页面输出流,封装的工具类
ResponseUtil.write(response, result);
return null;
}
还有附上封装的输出流工具类ResponseUtil:
package com.cms.util;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
/**
* ajax返回输出流工具类
* @author user
*
*/
public class ResponseUtil {
/**
* 页面输出
* @param response
* @param o
* @throws Exception
*/
public static void write(HttpServletResponse response, Object o)throws Exception{
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println(o.toString());
out.flush();
out.close();
}
}
现在开始编写后台页面,先在webapp目录下导入css文件,必须在static文件夹下,这才不会被shiro拦截;
这里的login文件夹就是我们的页面配置css文件等,还有我们的前台登录文件login.jsp;
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!doctype html>
<html lang="en" class="login-content" data-ng-app="materialAdmin">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>管理员登录界面</title>
<!-- Vendor CSS -->
<link href="${pageContext.request.contextPath}/static/login/css/material-design-iconic-font/css/material-design-iconic-font.min.css" rel="stylesheet" type="text/css">
<!-- CSS -->
<link href="${pageContext.request.contextPath}/static/login/css/app.min.1.css" rel="stylesheet" type="text/css">
<script type="text/javascript">
function submitData(){
var userName=$("#userName").val();
var password=$("#password").val();
if(userName==""){
alert("请输入用户名!");
return;
}
if(password==""){
alert("请输入密码!");
return;
}
$.post("${pageContext.request.contextPath}/manager2/login.do",{userName:userName,password:password},function(result){
if(result.success){
alert("登录成功");
}else{
alert(result.errorInfo);
}
},"json");
}
</script>
</head>
<body class="login-content" data-ng-controller="loginCtrl as lctrl">
<div class="lc-block" id="l-login" data-ng-class="{'toggled':lctrl.login === 1}">
<h1 class="lean">Login</h1>
<div class="input-group m-b-20">
<span class="input-group-addon">
<i class="zmdi zmdi-account"></i>
</span>
<div class="fg-line">
<input type="text" id="userName" name="userName" class="form-control" placeholder="userName" regex="^\w{3,16}$"/>
</div>
</div>
<div class="input-group m-b-20">
<span class="input-group-addon">
<i class="zmdi zmdi-male"></i>
</span>
<div class="fg-line">
<input type="password" id="password" name="password" class="form-control" placeholder="password" regex="^\w+"/>
</div>
</div>
<div class="clearfix"></div>
<div >
Copyright @2020 搜索微信公众号:程序员的时光
</div>
<a href="javascript:submitData()" class="btn btn-login btn-danger btn-float">
<i class="zmdi zmdi-arrow-forward"></i>
</a>
</div>
</body>
<script src="${pageContext.request.contextPath}/static/login/js/bower_components/jquery/dist/jquery.min.js"></script>
<script src="${pageContext.request.contextPath}/static/login/js/log.js"></script>
<!-- Angular -->
<script src="${pageContext.request.contextPath}/static/login/js/bower_components/angular/angular.min.js"></script>
<script src="${pageContext.request.contextPath}/static/login/js/bower_components/angular-resource/angular-resource.min.js"></script>
<script src="${pageContext.request.contextPath}/static/login/js/bower_components/angular-animate/angular-animate.min.js"></script>
<!-- Angular Modules -->
<script src="${pageContext.request.contextPath}/static/login/js/bower_components/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="${pageContext.request.contextPath}/static/login/js/bower_components/angular-loading-bar/src/loading-bar.js"></script>
<script src="${pageContext.request.contextPath}/static/login/js/bower_components/oclazyload/dist/ocLazyLoad.min.js"></script>
<script src="${pageContext.request.contextPath}/static/login/js/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<!-- Common js -->
<script src="${pageContext.request.contextPath}/static/login/js/bower_components/angular-nouislider/src/nouislider.min.js"></script>
<script src="${pageContext.request.contextPath}/static/login/js/bower_components/ng-table/dist/ng-table.min.js"></script>
<script src="${pageContext.request.contextPath}/static/login/js/app.js"></script>
<script src="${pageContext.request.contextPath}/static/login/js/controllers/main.js"></script>
<script src="${pageContext.request.contextPath}/static/login/js/controllers/ui-bootstrap.js"></script>
<!-- Template Modules -->
<script src="${pageContext.request.contextPath}/static/login/js/modules/form.js"></script>
</html>
我们进入数据库,查看用户名和密码,然后在后台登录即可;
会发现可以登录成功!