来源:原创(我的空间:http://groupby.cn)
在新的项目中使用了JWT密钥,效果不错。(还有JWT的异常处理,有待解决,但因为使用了vue前端框架,有没有异常已经暂时不影响使用了。)
先简单介绍一下JWT:
JWT 是 JSON Web Token的缩写,详细说明百度多的是,就不用我劳神了。
JWT的作用是加密和解密。它可以把一堆数据加密,并生成一串密文,也可以把密文解密,还原原始数据。
这样一来就可以用JWT加密个人登录信息,以便个人登录时,并提供密文,以证明自己是合法用户。
例如:把登录后的uid加密形成密文,然后发回个客户端,客户端以后每次都携带密文,访问带有权限验证的页面,服务服务端通过解密,得到uid,说明是已登录过的用户,并开放访问。
这样,就必须要求客户端在访问每个需要验证的页面,都必须携带密文,同时在服务端也就不需要使用session验证了。
顺便也避免了服务端session数据大的时候,引起的问题。
因为加密的密文不是很长,服务端解密是很快的,所以不会给服务端造成压力。(这是网上说的,我没有大数据测试的条件)
这样带来的好处是,多种设备使用一种密钥,都可以通用,可以避开手机端使用session等问题。
大概的使用方法:
下载jwt放在适当的目录。
在thinkphp加载jwt
定义一个数组,
用jwt加密这个数组,并得到一串密文。
把密文返回客户端,以便从此以后,客户端去到哪里都带着这一串密文。并依赖这一串密文作为访问服务端的权限。
即客户端打开另一个页面,并且需要验证的时候,客户端需要提交密文,服务端解密密文,还原得到密文里面的信息,
服务端再根据这些信息,作为下进入一步的条件,如果条件符合要求,就继续,不够不符合要求,就拒绝下一步。
例如,还原密文后,其中有用户id,就提供此用户的个人信息,如果解密失败,就停止。
安装:
我从这里下载了JWT
https://github.com/fireba
并把里面的src文件夹修改为fireba
这样我的JWT就安装在:
D:/www/Library/firebae/JWT目录下了,里面有四个文件,其中JWT.php是有用的。(另外,三个文件是跟异常有关的,还没用好)
之所以要加上目录fireba
所以,我的文件就是这样安排的:
D:/www/Library/firebae/JWT/JWT.php
D:/www/Library/firebae/JWT/BeforeValidException.php
D:/www/Library/firebae/JWT/ExpiredException.php
D:/www/Library/firebae/JWT/SignatureInvalidException.php
好了,接下来是thinkPHP的部分了,我用的是thinkPHP3.2.3版本
先用thinkPHP编写两个方法,测试一下TWJ是否可以正常使用:
注:我在配置中定义了Library,我觉得这样比较好用,不依赖thinkphp,即:
项目目录/Common/Conf/config.php
'Library' => 'D:/www/Library/',
下面是两个测试方法,先证明一下,JWT是否可以使用了。
<?php
namespace Home\Controller;
use Think\Controller;
require_cache(C('Library')."Fireba
use \Fireba
class UserController extends Controller {
public function one(){
$key = "jfdksajfkl;dsajfkdjsaklfdajffdsafdsfdsfdsfdsklfdsafdsafdsafdsdsajlkfdsa";
$token = array(
'uid' => 1050,
'username' => 'baby',
);
$jwt = JWT::encode($token, $key);
echo $jwt;
}
得到一串密文类似这个样子:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUuY29tIiwidXNlcmlkIjoiMTAwMDEiLCJ1c2VybmFtZSI6ImJhYnkiLCJ0cnVlbmFtZSI6ImEgbGl0dGxlIGJveSIsIm1vYmlsZSI6IjEzMzU2NDg1MjIifQ.9_SIzSonrft-BMqaKEp_KZzjwuSxgjHWeFc4cKhDXV8
public function two(){
$key = "jfdksajfkl;dsajfkdjsaklfdajffdsafdsfdsfdsfdsklfdsafdsafdsafdsdsajlkfdsa";
$str = isset($_GET['str']) ? $_GET['str'] : '';
if($str == ''){
exit('empty');
}
$decoded = JWT::decode($jwt, $key, array('HS256'));
if(!is_ob
echo "error";
}else{
$arr = json_decode(json_encode($decoded), true);
dump($arr);
$uid = $arr['uid']; //既然能拿到uid,那么就说明是有权限的用户,并且他的uid是1050。剩下的,只要有uid,该干什么就干什么好了。
}
}
}
下面是打开另一个页面,同时携带密文,类似这个样子:
某某项目/Home/Index/two?str=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUuY29tIiwidXNlcmlkIjoiMTAwMDEiLCJ1c2VybmFtZSI6ImJhYnkiLCJ0cnVlbmFtZSI6ImEgbGl0dGxlIGJveSIsIm1vYmlsZSI6IjEzMzU2NDg1MjIifQ.9_SIzSonrft-BMqaKEp_KZzjwuSxgjHWeFc4cKhDXV8
如果解密成功,就可以得到用户id。
同时,也说明试验成功。接下了来,是作实际的使用了。
==========实际的应用:用户登录===============
public function check_login(){
header("Access-Control-Allow-Origin: *");
$post_str = file_get_contents("php://input");
$post = json_decode($post_str, true);
$username = $post['username'];
$password = $post['password'];
$find_password = M('Pass')->where("username='$username'")->find();
if(如果密码正确){
$arr = array(
"uid" => $uid,
"username" => $find_password['username'],
);
//登录日志,不是必须的。
user_sign($find_password['uid'], 1);
//生成密钥
$jwt = JWT::encode($arr, $key);
$data['status'] = 200;
$data['msg'] = '登录成功';
$data['token'] = $jwt;
exit(json_encode($data));
}
}
==========用户访问有权限的页面=============
public function user_info(){
header("Access-Control-Allow-Origin: *");
$post_str = file_get_contents("php://input");
$post = json_decode($post_str, true);
$token = $post['token'];
if($token != ''){
$obj_token = JWT::decode($token, $key, array('HS256'));
$arr = json_decode(json_encode($obj_token), true);
$uid = $arr['uid'];
//下面是输出此会员的个人信息了。
...
}
}
使用效果:
因为前端使用了vue,后端程序需要作的工作就比以前好多了,不用再为模板嵌套数据了。
后端只要输出JSON数据就行了,加工数据、显示数据,就让前端js工作人员来完成好了。
最佳答案