总所周知,http是一种无状态协议,而当我们在传统的MVC模式下面,通常情况下是靠session来进行登陆验证。而现在的WEB已经发展到前后端分离的状态了,那么传统模式的session已经不能满足我们的需求。
使用AXIOS与thinkphp进行跨域(非跨域)通信的时候,在服务端是无法使用session的,那么我们怎么来判断用户是否登陆呢?这个时候我们则使用到了现在流行的JWT方法。
JWT是JSON Web Token的缩写JWT的作用是加密和解密。它可以把一堆数据加密,并生成一串密文,也可以把密文解密,还原原始数据。
这样一来就可以用JWT加密个人登录信息,以便个人登录时,并提供密文,以证明自己是合法用户。 例如:把登录后的uid加密形成密文,然后发回个客户端,客户端以后每次都携带密文,访问带有权限验证的页面,服务服务端通过解密,得到uid,说明是已登录过的用户,并开放访问。这样,就必须要求客户端在访问每个需要验证的页面,都必须携带密文,同时在服务端也就不需要使用session验证了。顺便也避免了服务端session数据大的时候,引起的问题。
因为加密的密文不是很长,服务端解密是很快的,所以不会给服务端造成压力。
这样带来的好处是,多种设备使用一种密钥,都可以通用,可以避开手机端使用session等问题。
同时,由于JWT是使用base64进行对称加密,也就是说是可以进行解密的,所以千万不要存储用户的密码等敏感信息!
同时,由于JWT是使用base64进行对称加密,也就是说是可以进行解密的,所以千万不要存储用户的密码等敏感信息!
同时,由于JWT是使用base64进行对称加密,也就是说是可以进行解密的,所以千万不要存储用户的密码等敏感信息!
好了,现在我们来介绍一下在thinkphp如何使用JWT
首先通过git获取https://github.com/firebase/php-jwt
把获取到的JWT放至thinkphp的目录下,目录结构如下:
Thinkphp/Library/Vender/Firebase/JWT
此时JWT文件里面应有4个文件分别为:
SignatureInvalidException.php
JWT.php
ExpiredException.php
BeforeValidException.php
除了JWT.php是我们要引入的主文件以外,其他文件不用直接引入。
我们在需要使用JWT的文件里面添加上命名空间
然后在要使用的操作类里面通过thinkphp的Vendor方法引入
public function Login(){
Vendor('Firebase.JWT.JWT');
// 使用JWT进行密钥签名
define('KEY', '28ksdfgdioaiowjqwreosod23ldmbsm2Xa'); // 自定义私有密钥
// 这里的$data是通过查询数据库里面是否有相应的用户名,并且密码正确返回的信息,我这里忽略了验证数据库信息的过程
if($data){
$nowtime = time();
$token = [
'iss' => 'teaxia', //签发者
'aud' => username, //jwt所面向的用户
'iat' => $nowtime, //签发时间
'nbf' => $nowtime, //生效时间(马上生效)
'exp' => $nowtime + 3600, // 过期时间1小时
'data' => [
'userid' => $data['id'], // 数据库的用户ID(请自行获取)
'username' => $data['name'] // 数据库的用户名(请自行获取)
]
];
$jwt = JWT::encode($token, KEY); // 通过JWT获取token
$this->ajaxReturn($jwt); // 返回用户token
}
}
以上,通过JWT生成用户TOKEN的过程就完成了,那么我们在验证TOKEN的时候,使用
$key = "28ksdfgdioaiowjqwreosod23ldmbsm2Xa"; // 私钥
$decoded = JWT::decode($jwtstr, $key, array('HS256')); // $jwtstr是每次请求时传过来的token
$arr = json_decode(json_encode($decoded), true); // 解密数据
这里面的$arr就是解密的用户信息,拿到这个用户信息就可以判断用户权限这些东西了
评论 (0)