【若依】开源框架学习笔记 01

主要内容

  • 记录登录日志的实现

页面视图

项目文件结构

实现方式

  1. Shiro登录认证方法 com.ruoyi.framework.shiro.realm.UserRealm
/**
 * 登录认证 
 */
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
{
    
    
    UsernamePasswordToken upToken = (UsernamePasswordToken) token;
    String username = upToken.getUsername();
    String password = "";
    if (upToken.getPassword() != null)
    {
    
    
        password = new String(upToken.getPassword());
    }

    SysUser user = null;
    try
    {
    
    
    	// 登录方法
        user = loginService.login(username, password);
    }
    catch (CaptchaException e)
    {
    
    
        throw new AuthenticationException(e.getMessage(), e);
    }
    // ... 以下代码此处先省略
}
  1. 进入 loginService.login(username, password) 方法
    com.ruoyi.framework.shiro.service.SysLoginService
/**
 * 登录
 */
public SysUser login(String username, String password)
{
    
    
    // 验证码校验
    if (ShiroConstants.CAPTCHA_ERROR.equals(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA)))
    {
    
    
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
        throw new CaptchaException();
    }
    // 用户名或密码为空 错误
    if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
    {
    
    
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
        throw new UserNotExistsException();
    }
    // 密码如果不在指定范围内 错误
    if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
            || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
    {
    
    
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
        throw new UserPasswordNotMatchException();
    }

    // 用户名不在指定范围内 错误
    if (username.length() < UserConstants.USERNAME_MIN_LENGTH
            || username.length() > UserConstants.USERNAME_MAX_LENGTH)
    {
    
    
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
        throw new UserPasswordNotMatchException();
    }

    // 查询用户信息
    SysUser user = userService.selectUserByLoginName(username);

    /**
    if (user == null && maybeMobilePhoneNumber(username))
    {
        user = userService.selectUserByPhoneNumber(username);
    }

    if (user == null && maybeEmail(username))
    {
        user = userService.selectUserByEmail(username);
    }
    */

    if (user == null)
    {
    
    
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
        throw new UserNotExistsException();
    }
    
    if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
    {
    
    
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.delete")));
        throw new UserDeleteException();
    }
    
    if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
    {
    
    
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark())));
        throw new UserBlockedException();
    }

    passwordService.validate(user, password);

    AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
    recordLoginInfo(user);
    return user;
}
  1. 异步工厂 (产生任务) com.ruoyi.framework.manager.factory.AsyncFactory
/**
  * 记录登录信息
  * 
  * @param username 用户名
  * @param status 状态
  * @param message 消息
  * @param args 列表
  * @return 任务task
  */
 public static TimerTask recordLogininfor(final String username, final String status, final String message, final Object... args)
 {
    
    
     final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
     final String ip = ShiroUtils.getIp();
     return new TimerTask()
     {
    
    
         @Override
         public void run()
         {
    
    
             String address = AddressUtils.getRealAddressByIP(ip);
             StringBuilder s = new StringBuilder();
             s.append(LogUtils.getBlock(ip));
             s.append(address);
             s.append(LogUtils.getBlock(username));
             s.append(LogUtils.getBlock(status));
             s.append(LogUtils.getBlock(message));
             // 打印信息到日志
             sys_user_logger.info(s.toString(), args);
             // 获取客户端操作系统
             String os = userAgent.getOperatingSystem().getName();
             // 获取客户端浏览器
             String browser = userAgent.getBrowser().getName();
             // 封装对象
             SysLogininfor logininfor = new SysLogininfor();
             logininfor.setLoginName(username);
             logininfor.setIpaddr(ip);
             logininfor.setLoginLocation(address);
             logininfor.setBrowser(browser);
             logininfor.setOs(os);
             logininfor.setMsg(message);
             // 日志状态
             if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER))
             {
    
    
                 logininfor.setStatus(Constants.SUCCESS);
             }
             else if (Constants.LOGIN_FAIL.equals(status))
             {
    
    
                 logininfor.setStatus(Constants.FAIL);
             }
             // 插入数据
             SpringUtils.getBean(SysLogininforServiceImpl.class).insertLogininfor(logininfor);
         }
     };
 }
  1. 异步任务管理器 (执行任务) com.ruoyi.framework.manager.AsyncFactory
/**
 * 异步任务管理器
 * 
 * @author liuhulu
 */
public class AsyncManager
{
    
    
    /**
     * 操作延迟10毫秒
     */
    private final int OPERATE_DELAY_TIME = 10;

    /**
     * 异步操作任务调度线程池
     */
    private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");

    /**
     * 单例模式 (饿汉模式)
     */
    private AsyncManager(){
    
    }

    private static AsyncManager me = new AsyncManager();

    public static AsyncManager me()
    {
    
    
        return me;
    }

    /**
     * 执行任务
     * 
     * @param task 任务
     */
    public void execute(TimerTask task)
    {
    
    
        executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
    }

    /**
     * 停止任务线程池
     */
    public void shutdown()
    {
    
    
        Threads.shutdownAndAwaitTermination(executor);
    }
}

猜你喜欢

转载自blog.csdn.net/Michelle_Zhong/article/details/116376259