Another Redis Desktop Manager

因为Redis Desktop Manager的Windows版本收费,不得不用Linux的免费版(如下图)

但有时候还是需要在Windows下使用Redis客户端,今天就来推荐下开源的免费应用:Another Redis Desktop Manager

GitHub地址:https://github.com/qishibo/AnotherRedisDesktopManager

亲测可用,亲测好用!

Windows版本下载地址:https://github.com/qishibo/AnotherRedisDesktopManager/releases

GitHub加速(亲测可用,亲测好用!)

如果你的GitHub经常抽风、速度慢,不妨试试以下办法。

亲测可用,好用!

1、去这两个网站查下IP地址

https://github.com.ipaddress.com/#ipinfo

https://fastly.net.ipaddress.com/github.global.ssl.fastly.net#ipinfo

2、修改Host

C:\Windows\System32\drivers\etc\hosts

写入或更新上述查到的IP

如果提示没有权限的话,可以右键点击hosts文件->属性->安全->编辑->点击Users->在Users的权限“写入”后面打勾。不过一般程序员都是有管理员权限,这点一般用不到。

199.232.69.194 github.global.ssl.fastly.net

140.82.112.3 github.com

3、开始飞速访问GitHub!!!

有关电脑操作的视频,我制作成了短视频,欢迎关注我的视频号观看。

这个方法不需要什么翻墙软件,如果发现打开慢了,就手动更新一下Host文件所对应的最新IP地址即可,免费又好用!

我家里是电信的网络,抽风非常厉害,下载很慢,Push代码一直不成功,我就用这个方法搞一下,马上就好了,详细看我的视频演示。

宝塔LNMP环境WordPress二级目录伪静态的设置

我这个站的WordPress位于主域名下的/shanghai/下面,原来国外主机用的Apache,现在这个是Nginx主机,所以伪静态的规则要重新改下。

宝塔可以很方便生成WordPress的顶级目录下的伪静态代码,但对于二级目录就的自己写了。

代码如下,把其中的/shanghai/改为你的目录即可。

location /
{
	 try_files $uri $uri/ /index.php?$args;
}

rewrite /wp-admin$ $scheme://$host$uri/ permanent;

location /shanghai/ {
index index.html index.php;
if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if (!-f $request_filename){
rewrite (.*) /shanghai/index.php;
}
}

国内主机请关闭WordPress自动更新

如果你部署在国内,你就知道升级的时候会不断地遇到升级失败,然后整站就不能访问了。

原因及重要性不必多说,那就说说关闭的方法吧:配置wp-config.php文件

全局配置文件wp-config.php位于wordpress程序根目录下的,在文件最后加入如下代码:

/** 关闭WordPress自动更新升级 */
define('AUTOMATIC_UPDATER_DISABLED', true);

经历了WordPress被种木马,回到国内(上海)主机

11月17日,Tony微信告诉我博客不能访问了,我一看被植入了js木马。

回想了一下11月4日还写博客来的,当时没有什么问题的。

赶紧问服务商有没有备份,最近的备份是哪天的?得到的答复是只保留最近3天的备份,找到最早的是11月14日的,可惜那时候已经被黑了。数据库和程序都被动了。

看了一下本地的备份,最近的是3月份的,也就是说半年多的博客要丢了。

头大,但工作挺忙,也顾不上了。

第一个念头就是,搬回阿里云,只要有付费的每日备份。

碰到青云有个双十一的活动,就随手买了个Linux的上海主机。正好也需要备案,就没急着捣鼓。等到了周末暂时利用新主机上的MySQL数据,看了一下被植木马的数据库,发现规律就是每篇文章都在结尾加入了一串javascript代码,同时站点的home和site的配置项都被改为木马的网址。

于是心里一喜,果断的写了REPLACE替换,清除了木马。

此时有了信心,拿起我的BeyondCompare文件比较利器,对WordPress程序与原版程序作了对比,发现不少上传的php文件,还有无后缀的木马文件。同时发现了被修改的程序文件,就这样逐渐的把程序的木马也清理了。

此时备案还在进行中,就在原来的国外主机上进行了程序和数据库的覆盖,当然了本地也保存了备份。

果然,网站正常了。欣喜的告诉小伙伴们,大家非常期待我分享如何清除木马的。

我还是比较谦虚的,希望等几天看看,是否还有未清理的木马,不然分享就是给自己丢人。

果不其然,替换后的第二天,程序又被植入了木马。

干净对虚拟机下的其他站点目录都进行了清理,还删除了几个漏网之鱼。

这下基本上放心了,此时备案也快完成了。

于是在新主机上玩BT宝塔,对服务器安全、网站目录、端口放行、SSL证书、WordPress二级目录下的伪静态等全部研究了一遍。

昨天,改了DNS,指向到了新主机。

老主机的数据全部删除了,希望在新主机上,在宝塔的协助下,能够安全不被黑。

这篇作为流水账,下次分享详细的木马清理过程,还有WordPress文件目录安全设置和伪静态的相关内容。

.NET程序连接Oracle一次执行多行SQL的注意事项

以前写的基于MSSQL数据库的.NET程序,不用担心SQL语句中的;或者换行符。但是因为要基于Infor LN的Oracle数据库进行开发,就碰到了;分号和换行的报错,同时一次执行UPDATE的多条更新语句时,也会报错。

Oracle.ManagedDataAccess.Client.OracleException:ORA-00911: invalid character

单行SQL如果有换行时,加了;就报上面的错,多行执行的时候,会报下面这种错误

Oracle.ManagedDataAccess.Client.OracleException:ORA-06550: line 1, column 1:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:

   ; <an identifier> <a double-quoted delimited-identifier>
The symbol ";" was substituted for "end-of-file" to continue.

虽然从网上能搜索到ExecuteNonQuery执行Oracle多条SQL的时候需要用到以下结构

BEGIN
SQL1;
SQL2;
SQL3;
END;

但是并没有人提到一定要确保整个SQL是一行,必须没有换行!

BEGIN
 UPDATE BAANDB.TWHINH225301 A
 SET A.T$WVID = -999
,A.T$ASGN = 1
,A.T$PKID = 'Troy'
,A.T$STLO = 'EMS'
 WHERE A.T$RUNN = 'CN432789'
 AND A.T$PICM = 1
 AND A.T$ASGN = 2
 AND A.T$PCKD = 2;
UPDATE BAANDB.TWHINH225301 A
 SET A.T$WVID = -999
,A.T$ASGN = 1
,A.T$PKID = 'Troy'
,A.T$STLO = 'EMS'
 WHERE A.T$RUNN = 'CN432785'
 AND A.T$PICM = 6
 AND A.T$ASGN = 2
 AND A.T$PCKD = 2;
END;

因为写日志看SQL方便,用了AppendLine,那么下面的代码中,需要手动替换下换行符:Replace(Environment.NewLine, ” “),如果还不放心,可以用Replace(“r\n”, ” “).Replace(‘\n’, ‘ ‘).Replace(‘\r’, ‘ ‘) 批量将各种换行符替换为空格。

            var result = 1;
            var sb = new StringBuilder();
            sb.AppendLine("BEGIN");
            foreach (var entity in list)
            {
                sb.AppendLine("UPDATE BAANDB.TWHINH225" + companyId + " A");
                sb.AppendLine("SET A.T$WVID = -999");
                sb.AppendLine(",A.T$ASGN = 1");
                if (!string.IsNullOrEmpty(entity.Picker))
                {
                    entity.Picker = dbHelper.SqlSafe(entity.Picker);
                    sb.AppendLine(",A.T$PKID = '" + entity.Picker + "'");
                }
                if (!string.IsNullOrEmpty(entity.StagingLocation))
                {
                    entity.StagingLocation = dbHelper.SqlSafe(entity.StagingLocation);
                    sb.AppendLine(",A.T$STLO = '" + entity.StagingLocation + "'");
                }
                // By Line
                sb.AppendLine("WHERE A.T$OORG = " + GetOrderOrigin(entity.OrderOrigin));
                sb.AppendLine("AND A.T$ORNO = '" + entity.OrderNumber + "'");
                sb.AppendLine("AND A.T$OSET = " + entity.OrderSet);
                sb.AppendLine("AND A.T$PONO = " + entity.Line);
                sb.AppendLine("AND A.T$SEQN = " + entity.SequenceNumber);
                sb.AppendLine("AND A.T$SERN = " + entity.Advice);
                // Check Assign Status
                sb.AppendLine("AND A.T$ASGN = 2");
                sb.AppendLine("AND A.T$PCKD = 2;");
            }
            sb.AppendLine("END;");
            try
            {
                ExecuteNonQuery(sb.ToString().Replace(Environment.NewLine, " "));
            }
            catch (Exception e)
            {
                LogUtil.WriteException(e);
                result = 0;
            }

            return result;

因为这个问题,还从大石头的新生命微信群发了红包求助,意外收获了结识了一个挺不错的开发者王振(王Bank)和他写的DbHelper:https://gitee.com/wangbank/BankDbHelper

.NET程序中如何解决Google Chrome浏览器iframe禁止跨域的SameSite的Cookie设置

这个问题是我们总部的一个外部应用,给到我们的客户每家一个iframe的嵌套页面,通过计算handshake的动态值,实现免登录的。这其中用到了Cookie和服务器端的Form认证。

伴随着谷歌浏览器(80版本之后对cookie的校验更加严格,SameSite属性默认值由None变为Lax)的升级,iframe中的Cookie跨域被默认禁用了,除非SameSite为None并Secure属性为True(强制SSL启用HTTPS访问)

经过印度第三方外包公司45天的调查处理,仍未解决。

经过远程会议,了解了现在团队已经做过的尝试,大的方向没错,目前未能解决的问题是

无法将2个Cookie的SameSite写成None

.ASPXAUTH
ASP.NET_SessionId

一开始我以为改用最原始的HTTPCookie的方式写就行了,但是这两个Cookie就是无法赋值。微软官网建议的在Web.config和Global.asax设置也没用。

好在透过Google看到有人提到用URL Rewrite工具,果然有效。

最终解决方案,用URL重写工具,在system.webServer节点写入Outbound规则如下:

    <rewrite>
      <outboundRules>
        <rule name="AddSameSiteCookieFlag">
          <match serverVariable="RESPONSE_Set-Cookie" pattern="^(.*)(ASP.NET|ASPXAUTH|SessionId)(=.*)$" />
          <action type="Rewrite" value="{R:0};SameSite=None" />
        </rule>
      </outboundRules>
    </rewrite>

而原有的<forms />认证信息中,必须加入requireSSL=”true”,总共涉及9行代码。

最终印度第三方外包公司的同事高高兴兴的去部署到服务器了。

一个有用的SQL Server拼接合并函数:STUFF

在ERP里面有个仓库的固定默认库位(Fixed Location)表,结构如下:

WarehouseCode, ItemCode, LocationCode

同一个仓库里的料号,可以允许设置多个固定库位,可以设置优先级来区分。

现在需要把一个物料在一个仓库的固定库位取出来,多个的时候用,分割连接在一起。

SELECT WarehouseCode,ItemCode,LocationCode = (
        STUFF((SELECT ',' + LocationCode FROM WMS_DefaultLocation WHERE WarehouseCode = A.WarehouseCode AND ItemCode = A.ItemCode AND Enabled = 1 AND DeletionStateCode = 0 ORDER BY LocationCode ASC FOR XML PATH('')),1,1,'')
    ) FROM WMS_DefaultLocation AS A WHERE A.Enabled = 1 AND A.DeletionStateCode = 0 GROUP BY WarehouseCode,ItemCode

这里用到了STUFF和 FOR XML PATH,本文主要介绍STUFF。

用法及详解

STUFF(param1, startIndex, length, param2)
将param1中自startIndex(SQL中都是从1开始,而非0)起,删除length个字符,然后用param2替换删掉的字符。

1、param1:一个字符数据表达式。param1可以是常量、变量,也可以是字符列或二进制数据列。
2、startIndex:一个整数值,指定删除和插入的开始位置。如果 startIndex或 length 为负,则返回空字符串。如果startIndex比param1长,则返回空字符串。startIndex可以是 bigint 类型。
3、length:一个整数,指定要删除的字符数。如果 length 比param1长,则最多删除到param1 中的最后一个字符。length 可以是 bigint 类型。
4、param2,返回类型。如果param1是受支持的字符数据类型,则返回字符数据。如果param1是一个受支持的 binary 数据类型,则返回二进制数据。

去掉了WordPress自定义摘要,翻页终于不错乱了

有读者反馈说看我博客的时候,翻页到后面或者搜索的第一页就出现页面错乱,我以为是个别文章的问题,昨晚花时间研究了一下,原来是WP摘要显示的问题。

因为2018年以前的博客是ASP平台的ZBlog,转换WordPress过来的时候,原来的自定义摘要也自动带过来了,但有些图片并没有替换src地址,还带着<#ZC_BLOG_HOST#>字样的url,狠了狠心,索性把所有的自定义摘要都删除了,可能会丢掉一些重要的信息。

我翻页到很多页,终于没有页面错乱了。