xianhc / apevolo-api

.Net 8 、SqlSugar ORM、Vue 2.X、RBAC、前后端分离的开箱则用的企业级中后台权限管理系统
https://www.apevolo.com
Apache License 2.0
809 stars 74 forks source link

GetIp 可以改的更简洁些 #13

Closed huster-songtao closed 2 years ago

huster-songtao commented 2 years ago
    /// <summary>
    /// 获取客户端IP地址
    /// </summary>
    /// <returns></returns>
    public static string GetIp()
    {
        if (HttpContextCore.CurrentHttpContext.Connection.RemoteIpAddress != null)
            return HttpContextCore.CurrentHttpContext.Connection.RemoteIpAddress.ToString();

        return "0.0.0.0";
    }

修改为:

    /// <summary>
    /// 获取客户端IP地址
    /// </summary>
    /// <returns></returns>
    public static string GetIp()
    {
        return HttpContextCore.CurrentHttpContext.Connection.RemoteIpAddress?.ToString() ?? "0.0.0.0";
    }

我对CurrentHttpContext这里的定义是有点疑问的,因为这个是静态类,如果高并发的时候,会不会拿不到正确的值? 我建议在控制器Controller里获取以后,作为参数传入,从Controller拿到的客户端IP肯定是正确的。

例如:\Controllers\AuthorizationController.cs

bool isTrue = await _onlineUserService.SaveAsync(jwtUserVo, token.ToString().Replace("Bearer ", ""));

修改为:

        // 保存在线信息
        string ipAddress = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "0.0.0.0";
        bool isTrue = await _onlineUserService.SaveAsync(jwtUserVo, token.ToString().Replace("Bearer ", ""), ipAddress);

\Core\IOnlineUserService.cs方法SaveAsync加上参数string ipAddress

    /// <summary>
    /// 保存在线用户
    /// </summary>
    /// <param name="jwtUserVo"></param>
    /// <param name="token"></param>
    /// <param name="remoteIpAddress">客户端IP地址</param>
    Task<bool> SaveAsync(JwtUserVo jwtUserVo, string token, string remoteIpAddress);

\Core\OnlineUserService.cs 方法SaveAsync加上参数string remoteIpAddress

    /// <summary>
    /// 保存在线用户
    /// </summary>
    /// <param name="jwtUserVo"></param>
    /// <param name="token"></param>
    /// <param name="remoteIpAddress">客户端IP地址</param>
    public async Task<bool> SaveAsync(JwtUserVo jwtUserVo, string token, string remoteIpAddress)
    {
        string browser = IpHelper.GetBrowserName();
        string address = IpHelper.GetIpAddress();

        OnlineUser onlineUser = new OnlineUser
        {
            UserId = jwtUserVo.User.Id,
            UserName = jwtUserVo.User.Username,
            NickName = jwtUserVo.User.NickName,
            Dept = jwtUserVo.User.Dept.Name,
            Browser = browser,
            Ip = remoteIpAddress,
huster-songtao commented 2 years ago
    /// <summary>
    /// 获取IP详细地址
    /// </summary>
    /// <returns></returns>
    public static string GetIpAddress()
    {
        try
        {
            string ip = GetIp();
            string pattern = @"^(([1-9]\d?)|(1\d{2})|(2[01]\d)|(22[0-3]))(\.((1?\d\d?)|(2[04]/d)|(25[0-5]))){3}$";
            if (!Regex.IsMatch(ip, pattern))
            {
                return "局域网IP";
            }

            string filePath = Path.Combine(_contentRoot, "wwwroot", "resources", "ip", "ip2region.db");

            using var search = new DbSearcher(filePath);
            var address = search.MemorySearch(ip).Region.Replace("0|", "");

            return address.Substring(address.Length - 4, 4) == "内网IP" ? "局域网IP" : address;
        }
        catch
        {
            // ignored
        }

        return "";
    }

修改为:

    /// <summary>
    /// 获取IP详细地址
    /// </summary>
    /// <returns></returns>
    public static string GetIpAddress(string ip)
    {
        try
        {
            string pattern = @"^(([1-9]\d?)|(1\d{2})|(2[01]\d)|(22[0-3]))(\.((1?\d\d?)|(2[04]/d)|(25[0-5]))){3}$";
            if (!Regex.IsMatch(ip, pattern))
            {
                return "局域网IP";
            }

            string filePath = Path.Combine(_contentRoot, "wwwroot", "resources", "ip", "ip2region.db");

            using var search = new DbSearcher(filePath);
            var address = search.MemorySearch(ip).Region.Replace("0|", "");

            return address.Substring(address.Length - 4, 4) == "内网IP" ? "局域网IP" : address;
        }
        catch
        {
            // ignored
        }

        return "";
    }

ip不是通过静态类获取的IP地址,而且作为参数传入的。

\Filter\AuditingFilter.cs

    /// <summary>
    /// 创建审计对象
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    private AuditLog CreateAuditLog(ActionExecutingContext context)
    {
        var routeValues = context.ActionDescriptor.RouteValues;
        var desc = ((ControllerActionDescriptor)context.ActionDescriptor).MethodInfo
            .GetCustomAttribute(typeof(DescriptionAttribute), true);

        var decs = HttpHelper.GetAllRequestParams(context.HttpContext); //context.ActionArguments;

        var auditLog = new AuditLog
        {
            Id = IdHelper.GetLongId(),
            CreateBy = _currentUser.Name ?? "",
            CreateTime = DateTime.Now,
            Area = routeValues["area"],
            Controller = routeValues["controller"],
            Action = routeValues["action"],
            Method = context.HttpContext.Request.Method,
            Description = desc == null ? "" : ((DescriptionAttribute)desc).Description,
            RequestUrl = HttpContextCore.CurrentHttpContext.Request.GetDisplayUrl() ?? "",
            RequestParameters = decs.ToJson(),
            BrowserInfo = IpHelper.GetBrowserName(),
            RequestIp = IpHelper.GetIp(),
            IpAddress = IpHelper.GetIpAddress()
        };

修改为:

    /// <summary>
    /// 创建审计对象
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    private AuditLog CreateAuditLog(ActionExecutingContext context)
    {
        var routeValues = context.ActionDescriptor.RouteValues;
        var desc = ((ControllerActionDescriptor)context.ActionDescriptor).MethodInfo
            .GetCustomAttribute(typeof(DescriptionAttribute), true);

        var decs = HttpHelper.GetAllRequestParams(context.HttpContext); //context.ActionArguments;

        // 获取客户端IP地址
        var remoteIpAddress = context.HttpContext.Connection.RemoteIpAddress?.ToString() ?? "0.0.0.0";
        var auditLog = new AuditLog
        {
            Id = IdHelper.GetLongId(),
            CreateBy = _currentUser.Name ?? "",
            CreateTime = DateTime.Now,
            Area = routeValues["area"],
            Controller = routeValues["controller"],
            Action = routeValues["action"],
            Method = context.HttpContext.Request.Method,
            Description = desc == null ? "" : ((DescriptionAttribute)desc).Description,
            RequestUrl = HttpContextCore.CurrentHttpContext.Request.GetDisplayUrl() ?? "",
            RequestParameters = decs.ToJson(),
            BrowserInfo = IpHelper.GetBrowserName(),
            RequestIp = remoteIpAddress,
            IpAddress = IpHelper.GetIpAddress(remoteIpAddress)
        };

RemoteIpAddress是通过context获取的,然后作为参数传入IpHelper.GetIpAddress。

下面代码列我修改后的代码: \Filter\GlobalExceptionFilter.cs

    /// <summary>
    /// 自定义返回格式
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    private string WriteLog(ExceptionContext context)
    {
        // 获取客户端IP地址
        var remoteIpAddress = context.HttpContext.Connection.RemoteIpAddress?.ToString() ?? "0.0.0.0";
        return string.Format("\r\n【异常信息】 : {0} \r\n" +
                             "【异常类型】 : {1} \r\n" +
                             "【请求类型】 : {2} \r\n" +
                             "【请求路径】 : {3} \r\n" +
                             "【请求内容】 : {4} \r\n" +
                             "【当前用户】 : {5} \r\n" +
                             "【当前IP】  : {6} \r\n" +
                             "【IP地址】  : {7} \r\n" +
                             "【浏览器】  : {8} \r\n" +
                             "【堆栈调用】 :{9} \r\n" +
                             "【完整异常】 :{10}", context.Exception.Message, context.Exception.GetType().Name,
            HttpContextCore.CurrentHttpContext.Request.GetDisplayUrl() ?? "", context.HttpContext.Request.Method,
            HttpContextCore.CurrentHttpContext.Request.Body.ReadToString() ?? "", _currentUser.Name ?? "",
            remoteIpAddress,
            IpHelper.GetIpAddress(remoteIpAddress),
            IpHelper.GetBrowserName(), context.Exception.StackTrace,
            ExceptionHelper.GetExceptionAllMsg(context.Exception));
    }

    /// <summary>
    /// 创建审计对象
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    private Log CreateLog(ExceptionContext context)
    {
        var routeValues = context.ActionDescriptor.RouteValues;
        var desc =
            ((ControllerActionDescriptor)context.ActionDescriptor).MethodInfo.GetCustomAttribute(
                typeof(DescriptionAttribute), true);

        //var dics = context.ActionArguments;

        var discs = HttpHelper.GetAllRequestParams(context.HttpContext);
        // 获取客户端IP地址
        var remoteIpAddress = context.HttpContext.Connection.RemoteIpAddress?.ToString() ?? "0.0.0.0";
        return new Log
        {
            Id = IdHelper.GetLongId(),
            CreateBy = _currentUser.Name ?? "",
            CreateTime = DateTime.Now,
            Area = routeValues["area"],
            Controller = routeValues["controller"],
            Action = routeValues["action"],
            Method = context.HttpContext.Request.Method,
            Description = desc == null ? "" : ((DescriptionAttribute)desc).Description,
            RequestUrl = HttpContextCore.CurrentHttpContext.Request.GetDisplayUrl() ?? "",
            RequestParameters = discs.ToJson(),
            BrowserInfo = IpHelper.GetBrowserName(),
            RequestIp = remoteIpAddress,
            IpAddress = IpHelper.GetIpAddress(remoteIpAddress),
            LogLevel = (int)LogLevel.Debug,
            ExceptionMessage = context.Exception.Message,
            ExceptionMessageFull = ExceptionHelper.GetExceptionAllMsg(context.Exception),
            ExceptionStack = context.Exception.StackTrace
        };
    }
xianhc commented 2 years ago

感谢你的提议,代码已优化