文章851
标签121
分类10

Sql 查看当前数据库下 最大的表 以及表大小

您可以使用以下SQL查询语句来查找当前数据库中最大的表以及它们的大小:

SELECT 
    table_name AS `Table`,
    ROUND(((data_length + index_length) / 1024 / 1024), 2) AS `Size (MB)`
FROM 
    information_schema.tables
WHERE 
    table_schema = DATABASE()
ORDER BY 
    (data_length + index_length) DESC
LIMIT 1;

该查询会从 information_schema.tables 视图中获取当前数据库中所有表的信息,并按照数据长度和索引长度之和进行降序排序。然后,通过 LIMIT 1 限制结果集只返回最大的表。

查询结果将会包含最大的表名以及该表的大小(以MB为单位)。

请注意,这个查询语句假设您正在使用的是当前数据库。如果您需要查询其他数据库中的表,请将 table_schema = DATABASE() 部分更改为适当的数据库名称。

WebAuthn: 真正的无密码身份认证

在数字时代,密码已成为我们日常生活和在线活动中不可或缺的一部分。尽管互联网已经发展了 20 多年,许多方面都有了巨大的改进,但只有密码,还是 20 年前的用法。

更准确的说,它的用户体验比 20 年前更差了。密码的强度现在要求越来越高,一般不能少于 8 个字符,还要包括特殊符号。另外,除了密码,通常还有其他验证(短信、图片识别、OTP 一次性密码等等)。

然而,即使变得如此麻烦,依然不能杜绝密码被盗、被破解、被钓鱼的风险。为了解决这些问题,WebAuthn 应运而生。

01 WebAuthn简介

WebAuthn,全称 Web Authentication,是由 FIDO 联盟(Fast IDentity Online Alliance)和 W3C(World Wide Web Consortium)联合制定的一套新的身份认证标准,旨在为网络身份验证提供一种更强大、更安全的方式,使用户能够使用他们的设备(如手机、USB 密钥或生物识别器)来进行身份验证,而无需使用密码。该标准于 2019 年 3 月 4 日正式成为 W3C 的推荐标准。目前主流的浏览器已经支持 WebAuthn,包括 Chrome、Firefox、Edge 和 Safari,更详细的支持情况可以通过 https://webauthn.me/browser-support 查看。

注:FIDO 联盟是一个非营利性组织,由 Google、微软、苹果、三星、高通、芯片厂商、支付公司、银行、电信运营商、认证公司等组成,旨在为用户提供更安全、更简单的身份验证体验。

02 WebAuthn的工作原理

WebAuthn 的原理并不复杂,它的核心是基于公钥的加密技术。在 WebAuthn 中,用户的身份认证是通过公钥和私钥来实现的。这很像我们平常使用配置了公私钥的 SSH 登录服务器的过程,只不过 WebAuthn 是在浏览器中实现的。

03 WebAuthn的组成部分

WebAuthn 由以下三个组成部分组成:

  1. 用户代理(User Agent):用户代理是指浏览器或者其他支持 WebAuthn 的客户端,它负责与用户进行交互,收集用户的身份认证信息,并将其发送给服务器。
  2. 身份验证器(Authenticator):身份验证器是指用于生成公钥和私钥的设备,如手机、USB 密钥或生物识别器。Windows Hello 和 macOS 的 Touch ID 也都是常见的身份验证器。
  3. Relying Party:Relying Party 是指需要进行身份认证的网站或应用程序,它负责生成挑战(Challenge)并将其发送给用户代理,然后验证用户代理发送的签名结果。
    上述三者在两个不同的用例(注册和认证)中协同工作,如下图所示。图中的各个实体之间的所有通信都由用户代理(通常是Web浏览器)处理。
    Xnip2024-02-24_12-04-29.png

04 WebAuthn的注册流程

Xnip2024-02-24_12-05-02.png
在注册时,用户端会生成一对公钥和私钥。其中,私钥存储在本地,而公钥则发送给服务器,服务端会将公钥与用户账户进行关联。详细的流程如下图所示:

Xnip2024-02-24_12-05-40.png

05 WebAuthn的认证流程

Xnip2024-02-24_12-05-55.png
在认证时,用户端会使用私钥对服务器端发送的挑战(Challenge)进行签名,然后将签名结果发送给服务器。服务器端会使用公钥对签名结果进行验证,从而完成身份认证。详细的流程如下图所示:

Xnip2024-02-24_14-07-32.png

你可以在 https://webauthn.me/ 上体验 WebAuthn 的注册和认证过程。

06 WebAuthn API

在上面的介绍中,涉及到两个主要的 API:

navigator.credentials.create()

navigator.credentials.get()

其中, navigator.credentials.create() 用于在注册阶段生成公钥和私钥。

navigator.credentials.get() 用于在认证阶段对服务端的挑战(Challenge)进行签名。

下面,我们将分别介绍这两个 API 的使用方法。

navigator.credentials.create()

const res = await navigator.credentials.create({
    publicKey: {
      // 随机的、加密安全的、至少 16 个字节的数据
      challenge: base64url.decode("<%= challenge %>"),
      // relying party 的信息
      rp: {
        name: "Awesome Corp", // Relying party 的名称
      },
      user: {
        id: base64url.decode("<%= id %>"),
        name: "<%= name %>",
        displayName: "<%= displayName %>",
      },
      authenticatorSelection: { userVerification: "preferred" },
      attestation: "direct",
      pubKeyCredParams: [
        {
          type: "public-key",
          alg: -7, // "ES256" IANA COSE Algorithms registry
        },
      ],
    },
  });

// 由于 res 并不是一个 JSON object,需要将 res 转换为 JSON object
const json = publicKeyCredentialToJSON(res);
// 将 json 发送给服务器
await post("/webauthn/register", {
    state: "<%= state %>",
    provider: "<%= provider %>",
    res: JSON.stringify(json),
});

navigator.credentials.get()

const res = await navigator.credentials.get({
    publicKey: {
      // 随机的、加密安全的、至少 16 个字节的数据
      challenge: base64url.decode("<%= challenge %>"),
      allowCredentials: [
        {
          id: base64url.decode("<%= id %>"),
          type: "public-key",
        },
      ],
      timeout: 15000, // 超过 15 秒未完成认证,则认为认证失败
      authenticatorSelection: { userVerification: "preferred" },
    },
  });

// 由于 res 并不是一个 JSON object,需要将 res 转换为 JSON object
const json = publicKeyCredentialToJSON(res);
// 将 json 发送给服务器
post("/webauthn/authenticate", {
    state: "<%= state %>",
    provider: "<%= provider %>",
    res: JSON.stringify(json),
});

07 WebAuthn的现状

说了这么多,WebAuthn 现在的应用情况如何呢?

目前,越来越多的服务已经开始正式支持 WebAuthn。就在今年 5 月,谷歌和微软同时宣布全面接入 WebAuthn,支持无密码登录。GitHub 也在几天前宣布开始公测无密码登录功能。

在去年的黑客马拉松中,我们就尝试使用 WebAuthn 实现了 MicroStrategy Library 的身份认证。点击播放下列视频,可查看实际效果:

原文地址 : https://zhuanlan.zhihu.com/p/644471521

WebAuthn 最大的优势就是它的安全性和便捷性,相信在不久的将来,它将会成为互联网身份认证的主流方式。

参考资料:

https://www.ruanyifeng.com/blog/2023/07/weekly-issue-262.html

https://webauthn.guide/#intro

https://webauthn.me/introduction

https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API

https://blog.techbridge.cc/2019/08/17/webauthn-intro

什么是WebAuthn:在Web上使用Touch ID和Windows Hello登录

对你的网站启用TouchIDWindows Hello身份验证。 WebAuthn简介:它如何工作以及如何实现。

#什么是WebAuthn?

Web Authentication API 是一个认证规范,允许网站使用内置的认证器(如Apple TouchID和Windows Hello)或使用安全密钥(如Yubikey)对用户进行认证。

Xnip2024-02-24_11-37-12.png

它利用公钥加密技术代替密码。用户注册时,将为该帐户生成一个公钥-私钥对。私钥安全地存储在用户的设备中,而公钥则发送到服务器。然后,服务器可以使用私钥来要求用户的设备签署“挑战书”(challenge)以验证用户身份。

#向WebAuthn注册

注册期间,网站通常会要求用户输入用户名和密码。通过WebAuthn,网站会生成一对公钥和私钥,将公钥发送给服务器,并将私钥安全地存储在用户的设备中。

Xnip2024-02-24_11-37-58.png

#使用WebAuthn登录

登录期间,网站通常会检查用户是否提供了正确的用户名和密码。借助WebAuthn,网站将发送挑战书并检查浏览器是否可以使用存储在用户设备中的私钥对询问进行签名。

Xnip2024-02-24_11-38-40.png

#纯JavaScript实现

要了解更多关于WebAuthn的信息,这里有一个关于如何用纯JavaScript实现WebAuthn的深入解释。请看 苹果在WWDC20上的指南

#注册

步骤1:你的站点请求服务器注册WebAuthn。

要求用户输入一些标识符(用户名、电子邮件等)。然后,向你的服务器发送请求,注册一个新的WebAuthn凭证。

步骤2:服务器指定一些选项来创建新的密钥对。

服务器指定了一个 PublicKeyCredentialCreationOptions 对象,该对象包含了创建一个新的 PublicKeyCredential(密钥对)所需的和可选的一些字段。

const optionsFromServer = {
    "challenge": "random_string", // 需要转换为ArrayBuffer
    "rp": {                        // 我的网站信息
      "name": "My Website",
      "id": "mywebsite.com"
    },
    "user": {                     // 用户信息
      "name": "anthony@email.com",                  
      "displayName": "Anthony",
      "id": "USER_ID_12345678910" // 需要转换为ArrayBuffer
    },
    "pubKeyCredParams": [
      {
        "type": "public-key",
        "alg": -7                  // 接受的算法
      }
    ],
    "authenticatorSelection": {
        authenticatorAttachment: "platform",
    },
    "timeout": 60000              // 以毫秒为单位
};
  • rp:指定依赖方的信息,用户注册/登录的网站。如果用户注册的是你的网站,那么你的网站就是依赖方。
  • id:主机的域名,不含协议和端口。例如,如果RP的来源是login.example.com:1337,那么 id 就是 login.example.comexample.com,而不是 m.login.example.com。
  • pubKeyCredParams : 服务器可接受哪些公钥类型。
  • alg : 一个数字,描述服务器接受的算法,并在COSE注册表中COSE算法下进行了描述。例如,-7用于ES256算法。
  • authenticatorSelection : (可选)限制验证器为平台或跨平台。使用 platform 允许像Windows Hello或TouchID这样的身份验证器。使用 cross-platform 允许身份验证器,如Yubikey

步骤3:在前端,使用选项创建新的密钥对。

使用 creationOptions 我们可以告诉浏览器生成一个新的密钥对。

// 请确保你已经将字符串转换为ArrayBuffer
// 如上所述
const credential = await navigator.credentials.create({
    publicKey: optionsFromServer 
});

返回的凭据( credential )将如下所示:

PublicKeyCredential {
    id: 'ABCDESKa23taowh09w0eJG...',
    rawId: ArrayBuffer(59),
    response: AuthenticatorAttestationResponse {
        clientDataJSON: ArrayBuffer(121),
        attestationObject: ArrayBuffer(306),
    },
    type: 'public-key'
}

步骤4:将凭证( credential )发送到你的服务器。

首先,你可能需要将 ArrayBuffer 转换为base64编码的字符串或仅仅是字符串。你需要在你的服务器中对此进行解码。

按照这些规范来验证服务器中的凭证。然后,你应该存储凭证信息,允许用户使用此WebAuthn凭证登录。

#登录

步骤1:向服务器发送请求以登录。

这允许服务器发送你的前端需要签名的询问。

步骤2:服务器发送挑战书和用户可以登录的WebAuthn凭据列表。

服务器指定一个 PublicKeyCredentialRequestOptions 对象,该对象包含要签署的挑战书和用户之前注册的WebAuthn证书列表。

const optionsFromServer = {
    "challenge": "somerandomstring",  // Need to convert to ArrayBuffer
    "timeout": 60000,
    "rpId": "mywebsite.com",
    "allowCredentials": [
      {
        "type": "public-key",
        "id": "AdPc7AjUmsefw37..."   // Need to convert to ArrayBuffer
      }
    ]
}

步骤3:前端签署挑战书。

PublicKeyCredential {
    id: 'ABCDESKa23taowh09w0eJG...',    // WebAuthn凭证ID
    rawId: ArrayBuffer(59),
    response: AuthenticatorAssertionResponse {
        authenticatorData: ArrayBuffer(191),
        clientDataJSON: ArrayBuffer(118),
        signature: ArrayBuffer(70),     // 我们需要验证的签名
        userHandle: ArrayBuffer(10),
    },
    type: 'public-key'
}

步骤4:将assertion发送到你的服务器并进行验证。

在将ArrayBuffers发送到服务器之前,你可能需要将其转换为字符串。按照验证assertion的规范进行。

当assertion被验证后,用户已经成功登录。现在你可以生成你的会话令牌或设置你的cookie,然后返回前端。

需要考虑的几件事

如果用户使用笔记本电脑的TouchID登录,你如何允许他们从其他人的笔记本电脑登录?

如果他们只能从自己的笔记本上登录,可能会有不好的用户体验。一个可能的方法是使用WebAuthn作为替代,并始终有一个后备登录方法(例如,使用魔术链接或OTP)。

为一个账户添加多个WebAuthn凭证。

你可能希望有一个“设置”页面,允许你的用户从其他设备登录WebAuthn,例如,如果他们想从笔记本电脑和iPad同时登录WebAuthn。浏览器不知道你在服务器中为用户保存了哪些凭证,如果你的用户已经注册了他们笔记本电脑的WebAuthn凭证,你需要告诉浏览器,这样它就不会创建一个新的凭证。使用 PublicKeyCredentialCreationOptions 中的 excludeCredentials

#WebAuthn支持情况

目前,并非所有浏览器都支持WebAuthn,但支持的浏览器越来越多。请访问FIDO网站,查看支持WebAuthn的浏览器和平台列表

Xnip2024-02-24_11-54-07.png

#结束

这应该涵盖使用WebAuthn注册和登录的基础知识,并帮助你在网站上实现它。

如果你想实现WebAuthn,这些文档可能会有所帮助:

#参考

我们引用了这些非常有用的文章来撰写这篇文章:

原文 : https://juejin.cn/post/6913894433888927752

PHP 通过反射 修改 私有静态变量

PHP中,可以使用反射来修改类的私有静态变量。以下是一个示例代码,演示如何使用反射来修改私有静态变量:

class MyClass {
    private static $privateStaticVariable = "Original Value";
    
    public static function getPrivateStaticVariable() {
        return self::$privateStaticVariable;
    }
}

// 使用反射修改私有静态变量
$reflectionClass = new ReflectionClass('MyClass');
$reflectionProperty = $reflectionClass->getProperty('privateStaticVariable');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue(null, "New Value");

// 测试修改是否成功
echo MyClass::getPrivateStaticVariable(); // 输出:New Value

在上面的示例代码中,我们定义了一个名为MyClass的类,其中包含一个私有静态变量$privateStaticVariable和一个公共静态方法getPrivateStaticVariable(),用于获取私有静态变量的值。

然后,我们使用反射来获取MyClass类,并使用ReflectionClassReflectionProperty类来获取和修改私有静态变量。首先,我们创建了一个ReflectionClass对象,传入类名MyClass作为参数。然后,我们使用getProperty()方法获取私有静态变量的ReflectionProperty对象。接下来,我们将setAccessible(true)调用设置为true,以便能够访问私有变量。最后,我们使用setValue()方法将私有静态变量的值修改为"New Value"。

最后,我们调用MyClass::getPrivateStaticVariable()方法来获取修改后的私有静态变量的值,并将其输出到屏幕上。输出应该是"New Value",表示私有静态变量已成功修改。

请注意,使用反射来修改私有静态变量可能会破坏封装性和导致不可预测的结果。建议谨慎使用,并确保了解代码的结构和设计。

[踩坑] Swoole . http response is unavailable (maybe it has been ended or detached)

今天查看 /var/log/php_error.log 抛错如下:

[23-Feb-2024 13:17:34 Asia/Shanghai] PHP Warning:  Swoole\Http\Response::header(): http response is unavailable (maybe it has been ended or detached) in ../Listen/Http.php on line 216
[23-Feb-2024 13:17:34 Asia/Shanghai] PHP Warning:  Swoole\Http\Response::end(): http response is unavailable (maybe it has been ended or detached) in ../Listen/Http.php on line 218

问题很明显

http response is unavailable (maybe it has been ended or detached
译 : http响应不可用(可能已结束或分离)

http 协议请求回包前 连接找不到 提前在其他位置回包了 或者说 客户端主动断开了.

">