异地补卡下的北京中年

我妈的老SIM卡不能用在iPhone里。因为我的卡就是从大卡剪过来的,所以骑车转了一大圈,临近年关,大部分修手机的店、合作营业厅都关了,最后一个卖手机的店里的老板说这种老卡不能剪,只能换卡。

之前听附近移动营业厅里的大堂经理说,换卡需要机主本人、身份证和服务密码,而且异地补卡只能去部分较大的营业厅。这个可以在网上营业厅里查到。

事先在网上营业厅重置了服务密码。第二天一早,去了最近的可以异地补卡的营业厅。工作人员给了张纸条,让写下手机号、服务密码,他们查了一下,说是鉴权失败,让第二天再去。留了营业厅的电话,事先让他们查一下,确认可以办了再去。

第三天早上十点,打电话过去,说是办异地补卡的人还没来。十一点再打过去,查了一下,说是可以办了。去之前差点没带手机,因为感觉就是办张卡,回来装也一样。事实证明,不带会后悔。

补卡也需要用手写板签字和人脸识别,因为是2d图像识别,所以很傻,需要摇头、点头、眨眼、张嘴,在张嘴这一步重试了很多次都失败……

补的第一张卡插到手机里不能识别,第二张才成功。

总结以上,异地补卡需要注意这些点:

  • 本人、身份证、服务密码(服务密码可以去网上营业厅重置,前提是卡还在,还能接到短信)
  • 去能办理异地补卡的营业厅(可以在网上营业厅查询,或者打客服电话)
  • 不要去太早,最好事先打电话让他们查一下,确认可以办了再去
  • 一定要带手机和开卡槽的工具,现场装卡测试
飞利浦电动牙刷HX9903/42使用感受

效果虽说没别人说的夸张,也的确刷得很干净,再就是缓解了胳膊的疲劳感。

有个问题。刚开始的几天,虽然电池已经充满,但是震动强度很一般,而且手柄底部的压力警示灯一直闪,试过拔掉刷头,问题还在,说明是手柄的问题。直到提示电量紧张后第二次充电,之后才恢复正常。

App、多种刷头、多种模式、压力警示和三级震动强度都是噱头,刷个牙而已,HX6730足够了,多交的几百块钱除了智商税,也就颜值和无线充电有点价值了。

电动牙刷不是个用了就回不去的东西,不过体验确实很好,刷牙不再是例行公事和负担,而是件挺有意思的事。

用OTP Auth替换了Authy

Authy的界面很花哨,但并不实用,管理多个两步验证账号时查询效率很低。OTP Auth采用更直观的列表布局,并且支持搜索,在用户体验和效率上有更大的优势。两者之间没有批量迁移数据的方式,只能逐个手动添加,很麻烦。

对XSS的防御更适合放在前端

很多项目会把转义操作放在后端接口获取参数的地方,从而忽略了这样一个问题——为什么主流框架都不在获取参数的方法里实现这一点?

以Laravel为例,如果可以这样获取转义后的参数:$request->escape('content'),代码会显得更优雅,而实际上只能用自己封装的函数手工转义:my_escape($request->get('content')),很丑陋的代码。

事实上,主流框架并非没有提供防御XSS的封装,只是都放在模板引擎里。这样做的依据是,XSS的原理是在原本用于展示的数据里包含了可执行的文本,但不是所有展示的位置都不应该包含可执行的文本。从另一角度上说,后端应该校验前端传递的数据,但不应该篡改它。

十公里租房补贴是个天才的福利制度

十公里以内是个很适合通勤的距离,以任何一种公共交通方式都可以把时间控制在半小时左右。

通勤时间每增加半小时,生活质量都会下降一个量级,而生活质量是会直接影响一个人的工作质量和稳定性的。所以有些公司有十公里内租房补贴的福利,这项制度天才的地方在于,如果把这些补贴以工资的形式发放,员工可能仍然会因为住得远导致幸福感很差,所以增加了很多不稳定的因素。这项制度间接地强制员工把自己收入的一部分用在提高自己生活质量上面,记得那个朝三暮四、朝四暮三的故事吗?公司花同样的钱,却得到了更大的价值。

癸丑望,月有食之

大概这是我第一次看月全食,暗红色,挺大个儿,但是拍出来就显得很小。论效果,iPhone X还不如几年前的LX5。

P1030593
P1030594

解决Laravel的Facade在被Mock时不自动注入依赖的一种方法

由于集成了Mockery,Laravel的Facade对单元测试非常友好,只需要一行代码就能实现mocking。

例如,测试目标方法中调用了订单工具类的一个方法,在使用依赖注入的方式时,需要用三行代码实现对这个方法的mocking:

1
2
3
$fakeOrderTool = m::mock(\App\Tool\Order::class);
$fakeOrderTool->shouldReceive('getById')->once()->with($id)->andReturn($fakeOrder);
$this->app->instance(\App\Tool\Order::class, $fakeOrderTool);

而用Facade是这样的:

1
OrderFacade::shouldReceive('getById')->once()->with($id)->andReturn($fakeOrder);

当测试目标方法也属于订单工具类时,需要部分mock这个类,所以还要加上一行:

1
OrderFacade::makePartial();

但如果订单工具类的构造方法里有需要注入的依赖关系,这里并不会被执行。所以我在工具类基类里封装了一个方法,用反射机制实现手工注入依赖关系:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 注入依赖,用于单元测试
*
* @return void
* @author donieli
* @since 5
* @version 5
*/
public function injectDependencies()
{
$reflector = new \ReflectionClass(get_class($this));
$params = $reflector->getConstructor()->getParameters();
$args = [];
foreach ($params as $param) {
$paramClass = $param->getClass();
if (empty($paramClass)) {
throw new \Exception('Dependency named '.$param->getName().' cannot be injected.');
}
$instance = app()->make($paramClass->getName());
$args[] = $instance;
}
call_user_func_array([$this, '__construct'], $args);
}

然后就可以这样处理:

1
2
3
OrderFacade::shouldReceive('getById')->with($id)->once()->andReturn($fakeOrder);
OrderFacade::makePartial();
OrderFacade::injectDependencies();
从Vultr新加坡迁移到洛杉矶

Vultr新加坡节点挂了两天了,不能翻墙简直什么都干不了。早上用CloudSpeed看了下,洛杉矶机房的响应速度还不错,就迁移了过去。

ShadowsocksR

这个很简单,用一键安装脚本

网络加速

用BBR,一键安装脚本

Tiny Tiny RSS

先按照之前的笔记安装ttrss。

然后重建一个空的ttrss的数据库:

1
2
docker exec f6d92ad8efba /usr/bin/psql -c "drop database ttrss"
docker exec f6d92ad8efba /usr/bin/psql -c "create database ttrss"

把数据库的备份复制到容器里并导入:

1
2
docker cp ttrss.sql f6d92ad8efba:/tmp/ttrss.sql
docker exec f6d92ad8efba /usr/bin/psql -d ttrss -f /tmp/ttrss.sql postgres

以root身份登录容器并删除备份文件:

1
2
docker exec -it --user root f6d92ad8efba /bin/sh
rm /tmp/ttrss.sql
Unlox:兼顾安全和体验的东西深得我心

买了Unlox。早就知道MacID,阴差阳错一直没买,所以这又是一次后知后觉的行为。

曾经用过一段时间ControlPlane,通过多种条件自动判断场景以启用或关闭锁屏密码。后来在一次系统升级之后就不能用了。因为这个东西本身体验也不是很好,免费的东西折腾起来太耗费精力,所以付费买体验也是个不错的选择。

有三个功能对我来说很有用。

首先是用Face ID解锁Mac。在Mac被唤醒后,iPhone X自动弹出解锁的通知,点击后Unlox被打开并自动调用Face ID,验证通过后Mac即被解锁。不过两次Face ID验证稍显繁琐,如果在iPhone锁屏界面验证通过后就自动解锁,体验会更好。不过我猜应该是iOS在这个地方不会通知到App。

其次是Tap解锁。用手指点击触摸板,点击次数和每次用的手指数目可以自定义。这个方式确实很方便。为了加强安全性,还可以设置当手机断开时禁用Tap解锁。

第三是离开时自动锁屏。可以设置当手机和Mac之间的蓝牙连接信号减弱多少时自动锁屏。虽然对于Macbook用处不大,也不失为忘记合上屏幕时的一种补救手段。

此外还有其它一些功能,例如通过手机锁定或解锁Mac、靠近时自动唤醒Mac等。

今年Apple应该会全系支持Face ID,所以这只是一个过渡方案。

密码管理的最佳实践

通密之所以不应该被过分指责,是因为有其存在的道理,没有哪种方案的管理成本比它更低,它不需要购买昂贵的1password,不需要担心临时用的时候突然想不起来,而且,只要这个密码足够强壮并且使用环境足够安全,大多数情况下也不会有什么问题。通密的问题在于它的风险成本太高,一旦一处泄漏,所有使用这个密码的地方都不安全。

另一个极端是,使用很复杂的密码,每个账号都不同,甚至用密码生成工具生成完全没有规律的随机字符串。这种方案的安全性很高,高到连你自己都记不住。

所以我需要这样一套好的方案,它应该在安全性和易用性之间取得一个比较好的平衡,并且随著方法论和工具链的进化,这个平衡可以无限逼近黄金分割点。

首先,密码应该是复杂但容易记住的。密码的复杂度和记忆负担并不成正比,例如如果你实在记不住“ppnn13%,dkstFeb1st”,那么这样呢——“娉娉袅袅十三余,豆蔻梢头二月初”。密码只是一个字符串,如果不去死记最终的值,而是字符串背后的规律,记忆的压力就会小很多。

但考虑到每个账号都想一个这样的密码是不现实的,而且怎么解决记忆密码和账号的对应关系的问题?所以进一步,可以用这样的密码当前缀,每个密码的前缀都一样,然后针对每个账号创造一个后缀,这个后缀应该是每个账号都不同的,且和账号有某种只有你自己才知道的关联,这样你可以随时根据账号计算出它的后缀。例如,可以用账号拼音首字母(当然,实际的规则应该更复杂一点)。

这样你就有了足够复杂、每个账号都不同并且很容易记住的密码。进一步地,在私有设备上可以利用文本替换功能(例如:Alfred for Mac的Snippets功能)快速输入通用前缀,某些支持按键编程的机械键盘会有更好的体验。

不过好记性不如烂笔头,为防万一,还是需要一个Plan B。主流的密码管理工具主要有这么几种:

  • 浏览器的账号记忆功能
  • 操作系统的keychain
  • 在线密码管理工具
  • 离线密码管理工具

浏览器一般是把密码以明文存储在本地的,firefox虽然有个主密码,但只是个幌子,别人仍然可以拿到它记录密码的数据库文件。这种做法的逻辑在于,设备上存储的数据的安全性由操作系统和用户负责,换句话说,用户不应该允许他人用自己的权限登录设备。但实际上很难避免这种情况,而且还要考虑到系统被入侵的可能。所以,只应该让浏览器记住那些最不重要的账号。

相对来说,操作系统的keychain一般有自动锁定的功能,会更安全一些。但是仍无法完全避免上述问题。而且keychain只能记录账号和密码,无法存储更多的附加信息。所以这种工具也只应该存储一些不重要的账号。

最著名的在线密码管理工具应该是Lastpass。关于它的安全性有很多种说法,不过我觉得但凡是敏感数据都不要存储到线上,所以这种方式不予考虑。

我倾向于使用离线的密码管理工具。1password据说很好用,但是太贵了,而且开源免费的keepass已经完全够用了。我在Mac上用KeePassXC,在iOS中用MiniKeePass,私钥文件离线存储,然后数据库文件用Dropbox同步就可以了。

此外,对于重要的账号,如果支持两步验证,一定要开启,然后用OTP Auth管理即可。

最终的方案是:

  • 方法论:统一的复杂但有规律的前缀+根据账号计算出来的后缀
  • 工具链:KeePass + OTP Auth + Dropbox