PHP 如何做 token 验证
很多做网站开发的朋友,都听过“token验证”这个词,总觉得是个很专业的技术概念,其实它离我们的日常操作并不远——比如你登录购物网站后,不用反复输密码就能加购商品,靠的就是它。今天就用大白话,讲讲PHP里的token验证到底是怎么回事。
先搞懂:token到底是个啥?
举个生活化的例子:你去小区门口的快递柜取件,每个人的取件码(就是token)是专属的,输对了才能打开自己的柜门,别人就算看到柜子也拿不了你的快递。对应到网站里,token就是一串由服务器生成的、专属用户的“取件码”,用来证明“你确实是这个账号的合法使用者”,不用每次都输一遍密码。

PHP做token验证,核心就是“生成专属token→存起来→验证token”这三步,每一步都能靠简单的代码实现,一点都不复杂。
第一步:生成专属token,给用户发“取件码”
当用户登录账号时,PHP就会生成一个独一无二的token。这个token不能随便写,得有两个特点:一是别人猜不到,二是和用户账号绑定。
比如可以用PHP自带的random_bytes函数生成随机字符串,再和用户的ID拼在一起,就像把你的门牌号(用户ID)和专属取件码(随机字符串)绑死了。生成后,把这个token返回给用户,通常存在浏览器的cookie里,或者存在前端的本地存储里——就像把取件码贴在你手机上,下次取件直接看手机就行。
举个最简单的例子:
`php
// 用户登录后,生成token
$userId = 123; // 假设这是当前登录用户的ID
$token = bin2hex(random_bytes(16)) . "_" . $userId; // 生成32位随机串+用户ID
setcookie("user_token", $token, time() + 3600*24*7, "/"); // 存7天,相当于取件码有效期7天
`
这样用户下次打开网站,不用再输密码,浏览器会自动把这个token发给服务器。
第二步:存好token,防止“假取件码”
生成token后,不能只存在用户那边,服务器也得有备份。不然随便一个人都能编个token冒充你。
最常见的是把token和对应的用户ID一起,存到数据库里的一张表(比如叫user_tokens),字段至少要有token(存生成的字符串)、user_id(绑定的用户)、expire_time(过期时间)。
比如刚才的token有效期是7天,那存的时候就把过期时间设为当前时间加7天。这样就算用户改了浏览器的存储,服务器这边还能核对真假。
第三步:验证token,核对“取件码对不对”
用户每次访问需要登录的页面(比如加购、查看订单),PHP都会先从浏览器里拿到用户带过来的token,再做两步核对:
第一步,先检查这个token有没有过期——如果过期了,就提示用户重新登录,相当于取件码失效了,得重新领;
第二步,去数据库里查,有没有这个token对应的记录,而且记录里的用户ID和当前要访问的页面是不是匹配——如果有,说明是真的取件码;没有,就是别人瞎编的token,直接拒绝访问。
简单的验证代码可以这么写:
`php
// 从浏览器拿到token
$token = $_COOKIE["user_token"] ?? "";
if (empty($token)) {
exit("请先登录");
}
// 拆分token的随机串和用户ID
list($tokenStr, $userId) = explode("_", $token);
// 查数据库:有没有这个token,且没过期
$pdo = new PDO("mysql:host=localhost;dbname=你的库名", "用户名", "密码");
$stmt = $pdo->prepare("SELECT user_id FROM user_tokens WHERE token = ? AND expire_time > NOW()");
$stmt->execute([$token]);
$dbUser = $stmt->fetchColumn();
// 核对通过才让访问
if ($dbUser == $userId) {
echo "欢迎访问,当前用户ID是" . $userId;
} else {
exit("token无效,请重新登录");
}
`
日常用的小提醒
实际开发里,token不能直接暴露在URL里,不然别人可能偷看到;而且要定期清理数据库里过期的token,不然数据会越存越多。其实PHP的框架(比如Laravel)早就封装好了这些逻辑,不用自己从零写,但搞懂这三步逻辑,遇到问题就不会懵啦。