1 在项目根目录下,安装jwt
composer require firebase/php-jwt
2 在登录控制器中加入生成token的代码
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class Login extends Cross
{
/**
* 显示资源列表
*
* @return \think\Response
*/
public function index(Request $request)
{
try{
validate(LoginValidate::class)->scene('login')->check($this->request->param());
$params = $request->param();
$db = new UserModel();
$result = $db->where("username='{$params['username']}' AND password='{$params['password']}'")->find();
if(!empty($result)){
$key = '!@#$%*&'; //这里是自定义的一个随机字串,应该写在config文件中的,解密时也会用,相当于加密中常用的 盐 salt
$token = array(
"iss" => $key, //签发者 可以为空
"aud" => '', //面象的用户,可以为空
"iat" => time(), //签发时间
"nbf" => time() + 3, //在什么时候jwt开始生效 (这里表示生成100秒后才生效)
"exp" => time() +200, //token 过期时间
"user_id" => $result['id'] //记录的userid的信息,这里是自已添加上去的,如果有其它信息,可以再添加数组的键值对
);
$jwt = JWT::encode($token, $key, 'HS256');
$this->response(200,"登录成功",['token'=>$jwt]);
}else{
$this->response(401,"用户名或者密码错误");
}
}catch (Exception $exception){
return $this->response(400,"请输入完整的信息",$exception->getMessage());
}
}
}
可以看到返回token
3 创建一个checkToken类进行解密
<?php
namespace app\api\controller;
use think\Controller;
use think\Request;
use app\api\controller\Cross;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class CheckToken extends Cross
{
protected $user_id;
protected function initialize()
{
parent::initialize(); // TODO: Change the autogenerated stub
// 解密token,存储用户id;
$key = '!@#$%*&';
$token = request()->header('token');
if(empty($token)){
$this->response(300,"你还没有登录");
}
try {
JWT::$leeway = 60; //当前时间减去60,把时间留点余地
$key = new Key($key, 'HS256');
$decoded = JWT::decode($token, $key); //HS256方式,这里要和签发的时候对应
$arr = (array)$decoded;
$this->user_id= $arr['user_id'];
} catch (Firebase\JWT\SignatureInvalidException $e) { //签名不正确
$this->response(301,"签名不正确");
} catch (Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
$this->response(301,"token失效");
} catch (Firebase\JWT\ExpiredException $e) { // token过期
$this->response(301,"token失效");
} catch (Exception $e) { //其他错误
$this->response(301,"未知错误");
}
}
}
所有需要登录操作的接口,都继承这个类
<?php
namespace app\api\controller;
use app\api\controller\CheckToken;
use think\Controller;
use think\Request;
class Home extends CheckToken
{
public function index(){
$this->response(200,'成功',$this->user_id);
}
}
在前端请求拦截器中,将获得的token设置为请求头
即可看到打印出来了用户id