Latest stories

JSON Web Token 的产生和认证

有两种认证方式,一种是基于 cookie 的认证,另一种是基于 token 的认证。后者实现往往是通过 JSON Web Token (以下简称 JWT)实现的。首先要说明一下两种认证方式的区别:

cookie-based authentication 的认证流程是:

  1. 用户填写 credentials,包括用户名,邮箱,密码这些内容;
  2. Server 服务器验证这些 credentials 是否正确,如果正确,则认证成功,创建一个 session 存储在数据库中;
  3. 将这个 session 的 session id 存储在浏览器端的 cookie 里;
  4. 接下来的每一个请求,都会带着这个 session id,Server 在接收请求后也会验证 session id 与 session 是否匹配;
  5. 一旦用户登出,client 端和 server 端的 session 均被摧毁;

token-based authentication:

  1. 用户填写 credentials,包括用户名,邮箱,密码;
  2. Server 服务器验证这些 credentials 是否正确,如果认证成功,则返回一个 signed token;
  3. 这个 token 会被存储在 client 端,大部分是在 localStorage,但也会存储在 session storage 或是 cookie 里;
  4. 接下来的每一个请求,都会带着 token 作为额外的 authentication 信息。
  5. Server 收到请求后,首先 decode 这个 token 并对 token 里的 signature 进行验证;

auto01

为什么会说 token-based 更好:

  1. stateless,也就是不需要再在 server 端保存一份纪录,但 server 端要保存用于签名时用的「secret key」;
  2. cookie 对跨域 CORS 操作不友好,token 则没有这个问题;

iPadOS 使用体验

今早安装了 iPadOS Development Beta 版本,体验了一会儿。因为不太敢拿 mac 升级 Catalina,据说文件系统改掉了。目前 mac 不太敢升,所以 Sidecar 功能暂时还没办法体验。iPhone 变化其实没那么大,也就只有 iPad 可以尝试了。提前做好备份,在苹果的开发者官网 Installing Apple Beta Software 下载安装 Xcode beta,安装完毕要打开运行,这样做的目的是帮助 iTunes 能够识别 iOS13。下载你所使用设备的 ipsw 文件。我是在这里下载的。然后在 iTunes 里更新就行了,注意要提前做好备份。

具体的安装教程也可以参考这个 YouTube 视频

下面按照给我带来惊喜的顺序,来简单谈一下这次的 iPadOS / iOS13。

阅读摘要 | issues #1

Complex life may only exist because of millions of years of groundwork by ancient fungi

在 hacker news 看到这样一则评论:对于 Fermi paradox 费米悖论的一个解释,死去的有机物通过数百万年,在这个星球上形成了丰富的化石燃料。因为这些石油化石资源的丰富,我们才能进入工业时代,才能进入电气时代。但有人反驳,即使没有这些化石,但只要存在了生命,就会有能量源,不管那是什么,就能帮助机器运转。

Why specialization can be a downside in our ever-changing world

作者认为专业化, 10000 小时理论,更倾向于在一个 kind or simple 的环境里发生。而事实大多数人所面临的环境都是极其复杂的, wicked 。重申了行动要优先于思考,并引用了 Herminia Ibarra 的话「We learn who we are in practice, not in theory」。最后,他认为让我们避免陷入自我的 cognitive biases 认知偏见的,是「science curiosity」。

JavaScript async and Promise

非常推荐先看一下参考链接里两个 youtube 视频,分别介绍了 event loop 和 setTimeout 的实现原理,这对于理解 JavaScript 里异步操作实现非常有帮助。其次是关于 Promise object 的手动实现,有一些抽象,因为包含了大量的 callback 函数。这里一定要分清楚,哪些是函数的声明,哪些是函数的调用。

Event loop

JavaScript 是一种 single thread 的语言。既然单一线程,那么在某个时间点,只能完成一项任务。于是

$.get('http://twitter.com')
$.get('http://youtube.com')
$.get('http://google.com')

在单线程下,如果某一行执行所需要的时间太久了,那么余下的的 command 也无法执行,程序就在那一行停滞下来了。我们把这个叫做 blocking。然而事实上,当我们在使用 setTimeout() 函数时,程序似乎不会出现 blocking。

console.log('hi')
setTimeout(() => console.log('there'), 0)
console.log('Welcome!')

// output:
// hi
// Welcome
// there

这里哪怕是设置 delay 为 0s, setTimeout() 里的函数也是在最后才执行,是怎么回事呢?

在 JavaScript 的执行环境中,所有的需要运行的函数是单线程的,按照次序会出现在 call stack 里。而通常,JavaScript 要么在 Browser 里运行,要么在 Node 环境运行,在 Browser 里运行时,会有一整套来自 Browser 提供的 web API,同理在 node 环境里也有相应的 API。 setTimeout() 函数就来自这些提供的 API 中。当我们 declare and call 一个 setTimeout() 函数时,Browser 会生成一个 timer 计时器,计时器的时间达到时, setTimeout() 里定义的 callback 函数会进入到一个叫 task queue 的容器中,此时程序会去检测 call stack 是否为空,当 call stack 为空时,会将 task queue 中最上层的函数移入 call stack 中进行执行。因此本质上来讲,由于有 web API 的加持,最终类似 setTimeout() 函数还是使用了多线程。只不过对于 JavaScript 来讲,一直是执行的是 call stack 里的内容,可以认为一直是单线程操作。

赤烛 - 『还愿』

『还愿』这个游戏,从去年放出预告开始,我就有关注。去年 7 月释出先导预告,内容是几支 80 年代广告和一档童星选秀节目。随后又陆续释出一些图片,比如贴满广告的大门的照片。去看网上关于这些预告的分析,发现这里不免夹杂了凶杀、分尸、拜神、祭祀等等恐怖惊悚的「奇情」元素。这些内容会让人联想到『血观音』,会联想到 93 年的香港电影『人肉叉烧包』,或者是15 年翁子光导演执导的『踏血寻梅』。这类电影都可以归纳为「奇情片」的概念,它们往往会是一些凶杀案件,和普通的犯罪片不同,犯罪手段通常都是凶狠残忍,而且动机难以捉摸。

奇情电影的背后往往蕴含着对时局动荡、社会不稳定的一种本能性的恐惧。要么直接诉苦,要么转移视线。

『奇异的……』 Episode 32 - 硬影像

『还愿』同样是具有「奇情片」内核的恐怖游戏。

以下内容涉及剧透。

『还愿』的故事背景设定在 80 年代的台湾。故事的叙述在 1980 年,1985 年,1986 年三个时间点互相穿梭,交叉叙事。80 年代的台湾究竟发生了什么?1979 年末发生了轰动一时的「美丽岛事件」。

棋盘上的「古墓丽影」

又是一个新年过去了。在年复一年不变的习俗和渐渐消淡的年味里,我把 Lara Croft Go 打通了。在 Square Enix 的 Go 游戏三部曲里,Hitman Go 是几年前玩过的,去年尝试了 Deus Ex Go。相比之下,更喜欢这部 Lara Go。Deus 里的科幻风太过浓重,Hitman Go 很贴近现代都市,在棋盘模拟的场景里,有熟悉的游泳池,花园,房屋里的家具等等。Lara Go 的场景都是放在野外,山窟洞穴,悬崖峭壁。如果另外两作的特点都是在「潜入」,那么 Lara Go 的特点则是在「冒险」。尽管有着固定的棋盘,每次只能前进一格,但这的确是个不折不扣的 Tomb Raider 式的冒险故事。

![Lara Go 1](/images/Game/Lara Go 1.jpg)

游戏整体美术风格,偏向折纸,背景的黑色剪影提供沉浸感。这样的美术风格在 iOS 平台并不少见。熟悉的有「纪念碑谷」「Alto’s Odyssey」。这样偏折纸的艺术风格,也比较适合这样的游戏模式。Square Enix 在 Go 系列游戏里想做的,是希望把 Go 系列做成一种桌游类型的游戏,所以这样的折纸风格再完美不过了。几年前在玩 Hitman Go 时,每一关的地图,都是按照桌游的包装盒来设计的。

以下内容涉及剧透。

「User Authentication with Passport and Koa 」Summary

上周在阅读 Express.js Blueprints 时看到 Authentication 的部分,就想着使用 Koa 去复现一遍。于是在网上看到这篇文章 User Authentication with Passport and Koa 。文章给出了源代码和详细的步骤。其中不乏遇到自己不熟悉的知识领域,比如 knex,postgresql 和 redis 等等。写这篇文章的目的:一是熟悉下在 koa 框架下的程序结构;二是对于自己不熟悉的知识领域的一个总结。

需要通过 brew 安装:

  • postgresql
  • redis

使用 npm 全局安装:

  • knex

初见 Koa.js

去网上检索 Koa,往往会看到诸多 Koa 和 Express 文章。Koa 的确是比 Express 更新的框架,因此也使用到了 ES6 更新的特性,比如 async/await。Koa 的核心 module 仅仅是 middleware kernel,Express 则提供了一套完整的解决方案,功能,routing,template 这些。Koa 要使用这些需要安装额外的 module。这样的对比,容易让人联想到 editor 和 IDE 的区别,前者注重轻量,可定制,后者追求大而全的设计。两种不同的设计哲学,我是偏爱前者,相信 less is more 的力量。当然,毕竟 Koa 和 Express 都是来自于同一个开发团队,很多基础概念是相通的。阅读本文,你需要提前了解以下内容:

  • Node.js 的异步特性及异步是如何实现的
  • 异步实现的几种方式,callback 到 Promise 到 async/await
  • 什么是 middleware?
  • ejs template engine

通过本文,你能了解到。Koa 最基础的 HelloWorld,它 如何渲染一个 template 页面,传递数据。什么是「Routing 路由」,路由在 Koa 中如何实现的。

异步 & callback

最近开始学习 Node.js。主要看两本书:Node.js in PracticeNode.js Design Patterns。前者类似于 o’reilly 的 cookbook 系列,整本书的编排是通过一个个 recipe,一个个具体的 problem&solution 实现的。后者就是 Packt Publishing 出品的一系列 Design Patterns 书籍。包括这两本书在内的许多讲解 Node.js 的书籍,都会不断强调两个关键词, asynchronous 和 non-blocking I/O。在最初开始学习编程的时候,无论是写一些算法题目,或是做一些本地测试,它都是同步的,即时响应的,单线程的,blocking I/O。但如果进入的网络领域,「异步」则会被不断提起。相比 synchronous,「异步」更加接近我们相处的真实世界。

这篇文章以 Node.js Design Patterns 第二章的 Web Spider 例子,探究思考在 Node.js 中是如何通过 callback 来实现异步操作的。

1/n- Cycle | 6kyu

Details

Let be n an integer prime with 10 e.g. 7.

1/7 = 0.142857 142857 142857 ....

We see that the decimal part has a cycle: 142857. The length of this cycle is 6. In the same way:

1/11 = 0.09 09 09 .... Cycle length is 2.

Task

Given an integer n (n > 1), the function cycle(n) returns the length of the cycle if n and 10 are coprimes, otherwise returns -1.

Exemples:

cycle(5) = -1
cycle(13) = 6 -> 0.076923 076923 0769
cycle(21) = 6 -> 0.047619 047619 0476
cycle(27) = 3 -> 0.037 037 037 037 0370
cycle(33) = 2 -> 0.03 03 03 03 03 03 03 03
cycle(37) = 3 -> 0.027 027 027 027 027 0
cycle(94) = -1 

cycle(22) = -1 since 1/22 ~ 0.0 45 45 45 45 ...

Note

  • Translators are welcome for all languages.

分类

标签