文章851
标签121
分类10

PHP 实现JWT认证

使用PHP实现JWT认证

JSON Web Token(JWT)是一种用于在网络应用间传递身份认证信息的开放标准。它由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。在本篇博客中,我们将介绍如何在PHP应用程序中使用JWT进行身份认证。

1. 安装依赖库

首先,我们需要使用Composer来管理我们的依赖库。在项目根目录下创建一个composer.json文件,并添加以下内容:

{
  "require": {
    "firebase/php-jwt": "^5.4"
  }
}

然后在命令行终端中运行以下命令安装依赖库:

composer install

2. 生成JWT

在PHP应用程序中生成JWT需要使用firebase/php-jwt库。以下是一个生成JWT的示例:

<?php
require 'vendor/autoload.php';

use Firebase\JWT\JWT;

$key = 'your_secret_key';
$payload = array(
    "user_id" => 1,
    "username" => "john.doe"
);

$jwt = JWT::encode($payload, $key, 'HS256');

echo "Generated JWT: " . $jwt;
?>

在上述示例中,我们使用JWT::encode()方法生成JWT。需要提供载荷(即数据)和一个秘钥来签名JWT。生成的JWT将在终端输出。

3. 验证JWT

在PHP应用程序中验证JWT需要使用相同的firebase/php-jwt库。以下是一个验证JWT的示例:

<?php
require 'vendor/autoload.php';

use Firebase\JWT\JWT;

$key = 'your_secret_key';
$jwt = 'your_generated_jwt';

try {
    $decoded = JWT::decode($jwt, $key, array('HS256'));
    $user_id = $decoded->user_id;
    $username = $decoded->username;

    echo "User ID: " . $user_id . "\n";
    echo "Username: " . $username . "\n";
} catch (Exception $e) {
    echo 'Invalid JWT: ' . $e->getMessage();
}
?>

在上述示例中,我们使用JWT::decode()方法验证JWT的有效性并解码其中的数据。如果JWT有效,则输出包含用户ID和用户名的信息。否则,将输出无效JWT的错误消息。

参考文献

结论

在本篇博客中,我们介绍了如何在PHP应用程序中使用JWT进行身份认证。通过使用firebase/php-jwt库,我们可以方便地生成和验证JWT。JWT提供了一种安全可靠的方式来传递身份认证信息,并在网络应用程序之间实现无状态认证。

请记住,在实际应用中,确保妥善保管JWT的秘钥,并采取其他安全措施(如HTTPS)来保护JWT的传输和使用。

OpenSSL/1.0.2k-fips: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

接上文说 对接三方平台接口, curl 请求接口 抛错

OpenSSL/1.0.2k-fips: error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

网上搜了很多 , 有说设置升级php8.0 有的说强制设置 1.0 还有的如下

curl --tlsv1.2 -X GET ....

都不解决问题.

原因就是第三方不支持 OpenSSL 1.0.2k 以下版本.

升级是可行的, 但不是升级php8.0, 而是本地的 openssl , 由于是亚马逊的centos 没有办法yum 升级(吐槽亚马逊).

$ wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz
$ tar xvf openssl-1.1.1k.tar.gz
$ cd openssl-1.1.1k/
$ ./config --prefix=/usr/local/openssl
$ make && make install

安装后 curl 请求扔失败 , 见了鬼了, 好吧重新安装下curl

wget https://curl.haxx.se/download/curl-8.6.0.tar.gz
tar zxf curl-8.6.0.tar.gz
cd curl-8.6.0/
./configure --without--with-ssl
make && make install
history |grep configure
./configure --prefix=/usr/local/curl/ --without-nss --with-ssl

安装失败 缺东西呀 .

yum install libpsl
yum install libpsl-dev
yum install libpsl-devel

./configure --prefix=/usr/local/curl/ --without-nss --with-ssl
make && make install

ls /usr/local/curl/bin/curl
/usr/local/curl/bin/curl -V

./configure --help
./configure --prefix=/usr/local/curl/ --without-nss --with-ssl --with-openssl=/usr/local/openssl/
make && make install

/usr/local/curl/bin/curl -V

上面是韵味同学给的 history .

记录一下 预防踩坑

PHP 对接三方接口踩坑 hash / base64_encode 等问题

如果您想使用PHP对接 一个第三方 xxx ,以下是一个示例代码片段,展示了如何使用PHP中的base64_encodehash函数与xxx进行对接:

这家平台对接 对于 openssl 有要求 不能对于1.0.2, 我的服务器环境 亚马逊Centos 需要编译安装.

// 输入数据
$data = '<compact json here>';

// 计算SHA-512散列
$digest = hash('sha512', $data, true);

// 进行base64编码
$base64 = base64_encode($digest);

// 替换base64编码中的字符
$base64url = str_replace(['+', '/', '='], ['-', '_', ''], $base64);

// 发送请求到xxx的API
$url = 'https://xxx.example.com/api/encrypt';
$params = [
    'data' => $base64url,
];

// 使用cURL发送POST请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

// 处理xxx的响应
if ($response !== false) {
    // 对响应进行处理...
} else {
    // 请求失败处理...
}

这个示例代码中,首先使用hash函数计算输入数据的SHA-512散列。然后,使用base64_encode对散列结果进行base64编码。接下来,使用str_replace函数替换base64编码中的字符,以生成URL安全的编码结果。最后,使用cURL库发送POST请求到 xxx 的API,并处理 xxx的响应。

请注意,这只是一个基本示例,实际情况可能需要根据xxx的API文档和要求进行适当的调整和验证。

PHP Warning: Redis::connect(): php_network_getaddresses: getaddrinfo failed: Name or service not known

当你在使用 Redis 扩展连接到 Redis 服务器时,可能会遇到 Redis::connect(): php_network_getaddresses: getaddrinfo failed: Name or service not known 的警告。这个警告通常表示 PHP 无法解析 Redis 服务器的主机名或无法连接到 Redis 服务器。以下是一篇关于解决这个问题的技术博客的 Markdown 格式示例:

解决 Redis 连接问题:php_network_getaddresses

在使用 Redis 扩展连接到 Redis 服务器时,可能会遇到以下警告信息:

PHP Warning: Redis::connect(): php_network_getaddresses: getaddrinfo failed: Name or service not known

这个警告通常表示 PHP 无法解析 Redis 服务器的主机名或无法连接到 Redis 服务器。下面是一些可能的解决方法:

1. 检查主机名和端口

确保你在连接 Redis 服务器时使用了正确的主机名和端口。检查你的代码,确认主机名和端口与 Redis 服务器的设置匹配。

2. 检查网络连接

确保 PHP 能够访问 Redis 服务器所在的网络。尝试使用 ping 命令或其他网络工具来测试与 Redis 服务器的连接。

3. 检查 DNS 解析

如果你使用的是主机名连接 Redis 服务器,确保主机名能够正确解析为有效的 IP 地址。你可以尝试使用 pingnslookup 命令来确认主机名是否能够解析为正确的 IP 地址。

4. 检查防火墙设置

如果你的服务器上启用了防火墙,确保已经允许 PHP 连接到 Redis 服务器的端口。检查防火墙设置,并确保允许来自 PHP 的网络流量通过 Redis 服务器的端口。

5. 检查 Redis 服务器状态

确保 Redis 服务器正在运行,并且服务正常。你可以尝试连接到 Redis 服务器并执行一些简单的操作,例如 PING 命令,来确认 Redis 服务器是否可用。

如果你仍然无法解决连接问题,建议参考 Redis 和 PHP 文档,查找更多关于连接 Redis 的指导和调试技巧。

希望以上解决方法能够帮助你解决 php_network_getaddresses 的问题,并成功连接到 Redis 服务器。

vmstat 命令 - 报告虚拟内存统计的工具

众所周知,计算机必须有称之为RAM(随机访问内存)的存储器使得计算机工作。RAM指的是插在计算机主板上的物理存储。这里的RAM被用于加载像浏览器、文字处理器这类的程序,实际上,你使用的程序都运行在内存上。

让我们假设你有2GB的内存。当你在运行操作系统时,你的可用内存可能只有1.5GB。接着你使用了大量的程序。当内存使用满之后,你可能再也无法加载更多的程序。浅显地说,计算机可能会说:"抱歉,你不能在运行更多的程序了,如果你还要运行其他的程序请先关闭一些程序。

photo_2024-03-18 19.23.37.jpeg

为了解决这个问题,包括Linux在内的各种操作系统使用了一个称之为虚拟内存的方法。这个方法会搜索最近不在使用的程序的内存区域,接着将它们拷贝到计算机硬盘上。这会腾出一些剩余内存空间给你有机会运行更多的程序。

为了监视虚拟内存的活动,我们使用vmstat工具。

什么是 vmstat

vmstat是一个提供报告虚拟内存统计的工具。它包括了系统内存、交换和实时处理器利用率。

如何运行 vmstat

和mpstat一样,vmstat包含在sysstat包中。如果你还没有,请安装sysstat包。

为了运行vmstat,只需在控制台输入vmstat。不带参数运行vmstat会显示vmstat的默认结果。

photo_2024-03-18 19.25.49.jpeg

让我们看下如何了解vmstat提供的信息:

Procs

procs有 r列和b列。r列代表等待访问CPU的进程数量。而b列意味着睡眠进程的数量。在这些列的下面,是它们的值。从上面的截图中,我门有2个进程正在等待访问CPU,0个睡眠进程。

Memory

memoryswpdfreebuffcache 这些列。这些信息和命令free -m相同。swpd列显示了有多少内存已经被交换到了交换文件或者磁盘。free列显示了未分配的可用内存。buff列显示了使用中的内存。cache列显示了有多少内存可以被交换到交换文件或者磁盘上如果一些应用需要他们。

Swap

swap显示了从交换系统上发送或取回了多少内存。si列告诉我们每秒有多少内存被从swap移到真实内存中(In)。so列告诉我们每秒有多少内存被从真实内存移到swap中(Out)。

I/O

io依据块的读写显示了每秒输入输出的活动。bi列告诉我们收到的块数量,bo列告诉我们发送的块数量。

System

system显示了每秒的系统操作数量。in列显示了系统每秒被中断的数量。cs列显示了系统为了处理所以任务而上下文切换的数量。

CPU

CPU告诉了我们CPU资源的使用情况。us列显示了处理器在非内核程序消耗的时间。sy列显示了处理器在内核相关任务上消耗的时间。id列显示了处理器的空闲时间。wa列显示了处理器在等待IO操作完成以继续处理任务上的时间。

按间隔时间运行vmstat

作为一个统计工具,使用vmstat最好的方法是使用间隔时间。你可以间断地捕捉系统状态。让我假设以5秒的间隔运行vmstat。只需要在你的控制台中输入vmstat 5就行。

photo_2024-03-18 19.27.47.jpeg

命令将会每5秒运行一次,直到你按下Ctrl-C来终止它。你也可以使用第二个参数来控制vmstat运行的次数。

photo_2024-03-18 19.28.28.jpeg

上面的命令会以5秒的间隔运行7次vmstat

显示活跃和非活跃内存

要这么做,你可以在vmstat后加入-a选项。这是个示例。

photo_2024-03-18 19.29.34.jpeg

显示磁盘统计数据总结

如果你想,vmstat也可以打印系统磁盘活动统计。使用-D选项就行。

photo_2024-03-18 19.30.53.jpeg

显示单位

你可以选择你想打印的显示单位字符。在-S后跟上k (小写,1000)、 K (大写,1024)、 m (小写,1000000)、 M (大写,1048576) 字节. 如果你不想选择单位,默认使用的是K (1024)。

photo_2024-03-18 19.33.44.jpeg

显示某个磁盘分区的详细统计数据

要这么做,你可以使用-p选项跟上设备名。这里有个例子。

photo_2024-03-18 19.34.22.jpeg

文件

vmstat实际上是使用这些文件获取的数据。

/proc/meminfo
/proc/stat
/proc/*/stat 

总结

如果你感觉系统运行超出内存了,在你增加物理内存前,这个工具可以帮助你确定问题的根本原因。通常上,你可以在控制台中输入man vmstat获取更多的关于vmstat的详细信息,这会为你显示vmstat的手册页。

">