小东Freeman + 关注

签名:我们爱我们的倒霉工作,也爱这千疮百孔的世界。

后台登录日志功能开发详解

发表于 6个月前   1407次查看    1评论  16 赞

网站后台管理安全十分重要,关系到能想到的数据的增删改查,排除黑客恶意攻击的可能,我们能做的就是尽可能早的发现漏洞,所以我们先做一个登录日志功能,如下图所示,目的是实时查看所有登陆的时间、地址、ip等等,把损失降到最小,下面把后台登录日志的开发过程讲一下

QQ截图20180902111814.png

数据库开发

建立一个登陆日志表

CREATE TABLE `houtailog` (
  `logid` int(11) NOT NULL AUTO_INCREMENT,
  `loginTime` datetime DEFAULT NULL,
  `local` varchar(32) NOT NULL,
  `loginIp` varchar(32) NOT NULL, 
  PRIMARY KEY (`logid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

我这里只添加了时间、地点、ip,你们可以根据在自己的需要添加


Java类开发

建立与数据库表想对应的bean

import java.util.Date;

/**
 * 
* <p>Title:Log4hou </p>
* <p>Description: 后台登录的日志类</p>
* @author  Fun言网
* @date    2018年9月2日上午10:09:23
 */
public class Log4hou {
	
	//登录id
	private int logid;
	//登录时间
	private Date loginTime;
	//登录地址
	private String local;
	//登录ip
	private String loginIp;
	public int getLogid() {
		return logid;
	}
	public void setLogid(int logid) {
		this.logid = logid;
	}
	public Date getLoginTime() {
		return loginTime;
	}
	public void setLoginTime(Date loginTime) {
		this.loginTime = loginTime;
	}
	public String getLocal() {
		return local;
	}
	public void setLocal(String local) {
		this.local = local;
	}
	public String getLoginIp() {
		return loginIp;
	}
	public void setLoginIp(String loginIp) {
		this.loginIp = loginIp;
	}

}


功能开发

1、登录验证成功后将登录人的ip、时间、地点写入数据库(登陆验证就不赘述了)

/**记录登录日志 **/
				//登陆的ip
				//由于反向代理
				 String ip  =  request.getHeader("x-forwarded-for"); 
				 if (ip == null || ip.length() == 0 || " unknown ".equalsIgnoreCase(ip)) {
			            ip = request.getHeader(" Proxy-Client-IP ");
			        }
			        if (ip == null || ip.length() == 0 || " unknown ".equalsIgnoreCase(ip)) {
			            ip = request.getHeader(" WL-Proxy-Client-IP ");
			        }
			        //获取真实ip
			        if (ip == null || ip.length() == 0 || " unknown ".equalsIgnoreCase(ip)) {
			            ip = request.getRemoteAddr();
			        }
			        System.out.println("ip为"+ip);
			   //获取当前地址(调用获取地址的工具类)
			   AddressUtils au=new AddressUtils();     
			   String local=au.getAddresses("ip="+ip,"utf-8");
			   //获取时间
			   log.setLoginTime(new Date());
			   log.setLoginIp(ip);
			   log.setLocal(local);
			   //写入数据库
			   houtaiService.houtailog(log);

获取地址的工具类:

import java.io.BufferedReader;  
import java.io.DataOutputStream;  
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.io.UnsupportedEncodingException;  
import java.net.HttpURLConnection;  
import java.net.URL;  
/** 
 *  根据IP地址获取详细的地域信息 
 */  
public class AddressUtils {   
 /** 
  * 
  * @param content 
  *            请求的参数 格式为:name=xxx&pwd=xxx 
  * @param encoding 
  *            服务器端请求编码。如GBK,UTF-8等 
  * @return 
  * @throws UnsupportedEncodingException 
  */  
 public String getAddresses(String content, String encodingString)  
   throws UnsupportedEncodingException {  
  // 这里调用pconline的接口  
  String urlStr = "http://ip.taobao.com/service/getIpInfo.php";  
  // 从http://whois.pconline.com.cn取得IP所在的省市区信息  
  String returnStr = this.getResult(urlStr, content, encodingString);  
  if (returnStr != null) {  
   // 处理返回的省市区信息  
   System.out.println(returnStr);  
   String[] temp = returnStr.split(",");  
   if(temp.length<3){  
    return "0";//无效IP,局域网测试  
   }  
   String region = (temp[5].split(":"))[1].replaceAll("\"", "");  
   region = decodeUnicode(region);// 省份  
    
            String country = "";  
            String area = "";  
            // String region = "";  
            String city = "";  
            String county = "";  
            String isp = "";  
            for (int i = 0; i < temp.length; i++) {  
                switch (i) {  
                case 1:  
                    country = (temp[i].split(":"))[2].replaceAll("\"", "");  
                    country = decodeUnicode(country);// 国家  
                    break;  
                    case 3:  
                        area = (temp[i].split(":"))[1].replaceAll("\"", "");  
                        area = decodeUnicode(area);// 地区   
                    break;  
                    case 5:  
                        region = (temp[i].split(":"))[1].replaceAll("\"", "");  
                        region = decodeUnicode(region);// 省份   
                    break;   
                    case 7:  
                        city = (temp[i].split(":"))[1].replaceAll("\"", "");  
                        city = decodeUnicode(city);// 市区  
                    break;   
                    case 9:  
                            county = (temp[i].split(":"))[1].replaceAll("\"", "");  
                            county = decodeUnicode(county);// 地区   
                    break;  
                    case 11:  
                        isp = (temp[i].split(":"))[1].replaceAll("\"", "");  
                        isp = decodeUnicode(isp); // ISP公司  
                    break;  
                }  
            }  
     
    System.out.println(country+"="+area+"="+region+"="+city+"="+county+"="+isp);  
   return region+city;  
  }  
  return null;  
 }  
 /** 
  * @param urlStr 
  *            请求的地址 
  * @param content 
  *            请求的参数 格式为:name=xxx&pwd=xxx 
  * @param encoding 
  *            服务器端请求编码。如GBK,UTF-8等 
  * @return 
  */  
 private String getResult(String urlStr, String content, String encoding) {  
  URL url = null;  
  HttpURLConnection connection = null;  
  try {  
   url = new URL(urlStr);  
   connection = (HttpURLConnection) url.openConnection();// 新建连接实例  
   connection.setConnectTimeout(2000);// 设置连接超时时间,单位毫秒  
   connection.setReadTimeout(2000);// 设置读取数据超时时间,单位毫秒  
   connection.setDoOutput(true);// 是否打开输出流 true|false  
   connection.setDoInput(true);// 是否打开输入流true|false  
   connection.setRequestMethod("POST");// 提交方法POST|GET  
   connection.setUseCaches(false);// 是否缓存true|false  
   connection.connect();// 打开连接端口  
   DataOutputStream out = new DataOutputStream(connection  
     .getOutputStream());// 打开输出流往对端服务器写数据  
   out.writeBytes(content);// 写数据,也就是提交你的表单 name=xxx&pwd=xxx  
   out.flush();// 刷新  
   out.close();// 关闭输出流  
   BufferedReader reader = new BufferedReader(new InputStreamReader(  
     connection.getInputStream(), encoding));// 往对端写完数据对端服务器返回数据  
   // ,以BufferedReader流来读取  
   StringBuffer buffer = new StringBuffer();  
   String line = "";  
   while ((line = reader.readLine()) != null) {  
    buffer.append(line);  
   }  
   reader.close();  
   return buffer.toString();  
  } catch (IOException e) {  
   e.printStackTrace();  
  } finally {  
   if (connection != null) {  
    connection.disconnect();// 关闭连接  
   }  
  }  
  return null;  
 }  
 /** 
  * unicode 转换成 中文 
  * 
  * @author fanhui 2007-3-15 
  * @param theString 
  * @return 
  */  
 public static String decodeUnicode(String theString) {  
  char aChar;  
  int len = theString.length();  
  StringBuffer outBuffer = new StringBuffer(len);  
  for (int x = 0; x < len;) {  
   aChar = theString.charAt(x++);  
   if (aChar == '\\') {  
    aChar = theString.charAt(x++);  
    if (aChar == 'u') {  
     int value = 0;  
     for (int i = 0; i < 4; i++) {  
      aChar = theString.charAt(x++);  
      switch (aChar) {  
      case '0':  
      case '1':  
      case '2':  
      case '3':  
      case '4':  
      case '5':  
      case '6':  
      case '7':  
      case '8':  
      case '9':  
       value = (value << 4) + aChar - '0';  
       break;  
      case 'a':  
      case 'b':  
      case 'c':  
      case 'd':  
      case 'e':  
      case 'f':  
       value = (value << 4) + 10 + aChar - 'a';  
       break;  
      case 'A':  
      case 'B':  
      case 'C':  
      case 'D':  
      case 'E':  
      case 'F':  
       value = (value << 4) + 10 + aChar - 'A';  
       break;  
      default:  
       throw new IllegalArgumentException(  
         "Malformed      encoding.");  
      }  
     }  
     outBuffer.append((char) value);  
    } else {  
     if (aChar == 't') {  
      aChar = '\t';  
     } else if (aChar == 'r') {  
      aChar = '\r';  
     } else if (aChar == 'n') {  
      aChar = '\n';  
     } else if (aChar == 'f') {  
      aChar = '\f';  
     }  
     outBuffer.append(aChar);  
    }  
   } else {  
    outBuffer.append(aChar);  
   }  
  }  
  return outBuffer.toString();  
 }  
 // 测试  
 public static void main(String[] args) {  
  AddressUtils addressUtils = new AddressUtils();  
  // 测试ip 219.136.134.157 中国=华南=广东省=广州市=越秀区=电信  
  String ip = "119.167.110.110";  
  String address = "";  
  try {  
   address = addressUtils.getAddresses("ip="+ip, "utf-8");  
  } catch (UnsupportedEncodingException e) {  
   // TODO Auto-generated catch block  
   e.printStackTrace();  
  }  
  System.out.println(address);  
  // 输出结果为:广东省,广州市,越秀区  
 }  
}

写入数据库的sql语句

insert into houtailog(loginTime,loginIp,local) values(#{loginTime},#{loginIp},#{local})


2、获取日志列表,这里就简单了,需要分页请参考:分页详细教程

sql语句:

select * from houtailog order by logid desc limit #{startPage},#{currentPage}


3、前端显示用foreach遍历就可以了

<table width="100%">
                                        <thead>
                                            <tr>
                                                <th>登录时间</th>
                               
                                                <th>地点</th>
                                                
                                                <th>IP</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                        <c:forEach items="${loglist }" var="log">
                                            <tr class="gradeX">
                                                <td><fmt:formatDate value="${log.loginTime }" pattern="yyyy.MM.dd HH:mm"/></td>
                                                <td>${log.local }</td>
                                                <td>${log.loginIp }</td>
                                                
                                            </tr>
                                           </c:forEach>
                                            <!-- more data -->
                                        </tbody>
                                    </table>


这样一个后台登录日志就完成了,有不懂的可以在下方评论,很简单也很实用。

16人已赞


本文由Fun言网 – 小东Freeman创作,转载请务必附上本文链接和出处,欢迎参与我们的付费投稿计划


你还没有登录,请先 登录注册!
文章评论1