蚊章汇 - 无密码
type: channel
link: https://linuxcn.bwsl.wang/tag/%E6%97%A0%E5%AF%86%E7%A0%81/
items: 硬核观察 #1014 微软发布 Azure Linux 正式版
items: 无密码验证：客户端

硬核观察 #1014 微软发布 Azure Linux 正式版
type: item
date: 2023-05-28T02:11:53+08:00
description: 微软发布 Azure Linux 正式版在内部使用 Azure Linux 两年，并从 2022 年 10 月开始公开预览后，微软本周终于正式提供其 Azure Linux。Azure Linux 是 Azure Kubernetes 服务（AKS）的一个开源容器主机操作系统，它针对 Azure 进行了优化，旨在使开发人员更容易使用微软的工具来部署和管理容器工作负载。Azure Linux 源于微软的 CBL-Mariner 项目，是“自我独立的 Linux 发行版”，而非衍生自 Ubuntu 或 Fedora。消息来源：The Register老王点评：这不是微软的第一个 Linux 发行版，也不是最后一个发行版。使用 XFS 的系统暂时不要升级到 Linux 6.3上周以来，多个用户已经报告了在升级到 Linux 6.3 稳定内核时，XFS 文件系统的元数据损坏问题。当他们在基于 XFS 的服务器上运行 Linux 6.3 时，服务器不断崩溃。据报道，Linux 6.4 内核对一些受影响的用户来说工作正常，这让人觉得一些补丁可能没有很好地回传到较新的 Linux 6.3 的小版本。消息来源：Phoronix老王点评：这比较罕见，无论是 Linux 稳定版，还是文件系统，出现这样的问题太不应该了。或许我们该担忧 Linux 内核的质量把控了？当然，谨慎的系统管理员从来在更新上都是“懒惰”的。Bitwarden 进军无密码安全领域可悲而简单的事实是，密码泄露正变得像人们闯红灯一样普遍。密码机制已经过时，大约一半的 IT 决策者认为他们使用的应用程序中缺乏无密码设计是主要原因。而无密码技术中的 密码钥匙 Passkey 可以通过设备上已有的密码、指纹、面部识别等，来替代用户的账户密码登录其它服务。它不仅消除了对密码、用户名和双因素认证（2FA）的需求，而且还通过减轻钓鱼攻击的风险来增强用户的安全性。流行的开源密码管理程序 Bitwarden 推出了 Passwordless.dev，这是一个开发者工具包，用于将无密码技术集成到网站和应用程序中。消息来源：The Newstack老王点评：作为著名的密码管理软件，面对无密码时代的来临，也不得不“与时俱进”。

无密码验证：客户端
type: item
date: 2018-07-12T19:41:37+08:00
description: 我们继续 无密码验证 的文章。上一篇文章中，我们用 Go 写了一个 HTTP 服务，用这个服务来做无密码验证 API。今天，我们为它再写一个 JavaScript 客户端。我们将使用 这里的 这个单页面应用程序（SPA）来展示使用的技术。如果你还没有读过它，请先读它。记住流程：用户输入其 email。用户收到一个带有魔法链接的邮件。用户点击该链接、用户验证成功。对于根 URL（/），我们将根据验证的状态分别使用两个不同的页面：一个是带有访问表单的页面，或者是已验证通过的用户的欢迎页面。另一个页面是验证回调的重定向页面。伺服我们将使用相同的 Go 服务器来为客户端提供服务，因此，在我们前面的 main.go 中添加一些路由：router.Handle("GET", "/...", http.FileServer(SPAFileSystem{http.Dir("static")})) type SPAFileSystem struct { fs http.FileSystem } func (spa SPAFileSystem) Open(name string) (http.File, error) { f, err := spa.fs.Open(name) if err != nil { return spa.fs.Open("index.html") } return f, nil } 这个伺服文件放在 static 下，配合 static/index.html 作为回调。你可以使用你自己的服务器，但是你得在服务器上启用 CORS。HTML我们来看一下那个 static/index.html 文件。 Passwordless Demo 单页面应用程序的所有渲染由 JavaScript 来完成，因此，我们使用了一个空的 body 部分和一个 main.js 文件。我们将使用 上篇文章 中的 Router。渲染现在，我们使用下面的内容来创建一个 static/js/main.js 文件：import Router from 'https://unpkg.com/@nicolasparada/router' import { isAuthenticated } from './auth.js' const router = new Router() router.handle('/', guard(view('home'))) router.handle('/callback', view('callback')) router.handle(/^\//, view('not-found')) router.install(async resultPromise => { document.body.innerHTML = '' document.body.appendChild(await resultPromise) }) function view(name) { return (...args) => import(`/js/pages/${name}-page.js`) .then(m => m.default(...args)) } function guard(fn1, fn2 = view('welcome')) { return (...args) => isAuthenticated() ? fn1(...args) : fn2(...args) } 与上篇文章不同的是，我们实现了一个 isAuthenticated() 函数和一个 guard() 函数，使用它去渲染两种验证状态的页面。因此，当用户访问 / 时，它将根据用户是否通过了验证来展示主页或者是欢迎页面。验证现在，我们来编写 isAuthenticated() 函数。使用下面的内容来创建一个 static/js/auth.js 文件：export function getAuthUser() { const authUserItem = localStorage.getItem('auth_user') const expiresAtItem = localStorage.getItem('expires_at') if (authUserItem !== null && expiresAtItem !== null) { const expiresAt = new Date(expiresAtItem) if (!isNaN(expiresAt.valueOf()) && expiresAt > new Date()) { try { return JSON.parse(authUserItem) } catch (_) { } } } return…