4. 集成jwt获取token接口:
(1). 密码加密:
①. 不使用md5来加密,而使用PHP的password_hash()函数来进行加密.
②. 文档:
https://www.php.net/manual/zh/function.password-hash.php
③. password_hash()使用足够强度的单向散列算法创建密码的散列(hash).
④. password_hash()兼容crypt().即crypt()创建的密码散列也可用于password_hash().
⑤. password_hash的第二个参数PASSWORD_BCRYPT是为了兼容crypt的散列密码.
(2). JWT逻辑:
①. 不可能每次用户请求的时候,都会去产生新的token,不断的去生成token.
②. 如果用户反复请求10次,就会有10个token,然后10个人分别用不同的token来完成请求.
③. 第二方面是前端的token续期问题,如果每次生成一个新的token,前端就没有依据了.
④. 基本流程
a. 用户验证成功后,生成token并同时保存至redis中,并且返回ttl.
b. 用户下次请求token时,返回redis里保存的token.
(3). 创建models实体:
①. 修改bean.php中db的连接设置.
②. 生成models实体文件:
php bin/swoft entity:create --table=users_main --path=@app/Models
③. 返回结果:
a. 正确:{"access_token": "xxx", "expire_in": 7200} // expire_in告诉客户端token还有多久过期
b. 错误:{"errcode":40013, "errmsg": "xxxxooo"}
(4). app\Validator\TokenValidator.php:
namespace App\Http;
use App\Models\UsersMain;
use Firebase\JWT\JWT;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use Swoft\Http\Server\Annotation\Mapping\RequestMethod;
use Swoft\Validator\Exception\ValidatorException;
use Swoft\Redis\Redis;
/**
* @Controller()
*/
class AccessToken {
/**
* @RequestMapping(route="/access_token", method={RequestMethod::POST, RequestMethod::OPTIONS})
*/
public function getToken()
{
// 非注解式验证
$params = validate(jsonParams(), "tokenValidator");
// 验证通过,$params是一个数组
// array(2) {["username"] => string(8) "asfdsfsd", ["password"] => string(8) "2ddd1222"}
["username" => $userName, "password" => $pwd] = $params;
/**
* @var UsersMain $result // 不显示下面getUserPass加上以下这句
*/
$result = UsersMain::where('user_name', $userName)->select("user_pass")->first();
// 查询数据库比对密码是否一致
if (!empty($result) && password_verify($pwd, $result->getUserPass())) {
$rKey = "token_" . $userName;
if ($getTokenFromRedis) {
$tokenStr = Redis::get($rKey);
} else {
$token = ["username" => $userName];
// abcde是秘钥key,HS256表示对称加密
$tokenStr=JWT::encode($token, "abcde", 'HS256');
Redis::setex($rKey, 50, $tokenStr);
}
return [
// 如果是JWT生成的token,也建议去redis中取,写死值可能会有延迟产生
"access_token" => $tokenStr, "expire_in" => Redis::ttl($rKey)
];
} else {
throw new ValidatorException("用户名密码不正确");
}
}
}
注:
①. 访问POST:http://192.168.33.88:8306/access_token即可获取token值.