一、安装jwt

地址 : https://github.com/firebase/php-jwt

composer require firebase/php-jwt

二、前端 js

lazy.png

/**

* 设置cookie

* @param $k

* @param $val

* @returns {boolean}

*/

function addCookie(name,value,days=1,path='/'){ /**添加设置cookie**/

var name = escape(name);

var value = escape(value);

var expires = new Date();

expires.setTime(expires.getTime() + days * 3600000 * 24);

//path=/,表示cookie能在整个网站下使用,path=/temp,表示cookie只能在temp目录下使用

path = path == "" ? "" : ";path=" + path;

//GMT(Greenwich Mean Time)是格林尼治平时,现在的标准时间,协调世界时是UTC

//参数days只能是数字型

var _expires = (typeof days) == "string" ? "" : ";expires=" + expires.toUTCString();

document.cookie = name + "=" + value + _expires + path;

}

function getCookieValue(name){ /**获取cookie的值,根据cookie的键获取值**/

//用处理字符串的方式查找到key对应value

var name = escape(name);

//读cookie属性,这将返回文档的所有cookie

var allcookies = document.cookie;

//查找名为name的cookie的开始位置

name += "=";

var pos = allcookies.indexOf(name);

//如果找到了具有该名字的cookie,那么提取并使用它的值

if (pos != -1){ //如果pos值为-1则说明搜索"version="失败

var start = pos + name.length; //cookie值开始的位置

var end = allcookies.indexOf(";",start); //从cookie值开始的位置起搜索第一个";"的位置,即cookie值结尾的位置

if (end == -1) end = allcookies.length; //如果end值为-1说明cookie列表里只有一个cookie

var value = allcookies.substring(start,end); //提取cookie的值

return (value); //对它解码

}else{ //搜索失败,返回空字符串

return "";

}

}

//删除cookie

function deleteCookie(name,path='/'){ /**根据cookie的键,删除cookie,其实就是设置其失效**/

var name = escape(name);

var expires = new Date(0);

path = path == "" ? "" : ";path=" + path;

document.cookie = name + "="+ ";expires=" + expires.toUTCString() + path;

}

//退出

function logout() {

deleteCookie('username');

deleteCookie('token');

location.reload();

}

lazy.png

三、后端

1、保存注册信息

lazy.png

/**

* 保存注册信息

* @return false|string

*/

public function save(){

$post=post();

$post['username']=trim($post['username']);

$post['password']=password_hash($post['password'],PASSWORD_DEFAULT);

$post['create_time']=time();

$memberModel=new MemberModel();

return $memberModel->addOne($post);

}

lazy.png

2、处理登录 ,返回token,前端保存cookie ,下次访问页面带上token

lazy.png

public function login(){

$post=post();

if(!isset($post['username']) || empty($post['username'])) return __error('请输入用户名');

if(!isset($post['password']) || empty($post['password'])) return __error('请输入密码');

$memberModel=new MemberModel();

$member=$memberModel->getOneByName(trim($post['username']));

if($member==false) return __error('该用户不存在');

if(!password_verify($post['password'],$member['password'])) return __error('密码错误');

//生成token

$token=JwtService::createJwt(trim($post['username']));

$data=array(

'username'=>$post['username'],

'token' =>$token['data']

);

return __success('登录成功',$data);

}

lazy.png

3、JwtBaseCtrl 父级控制过滤 校验token

lazy.png

protected function __construct()

{

$cookie=$_COOKIE;

$data=isPost()?$_POST:$_GET;

//判断token是否过期或不存在

if(isAjax()){

if(!isset($data['token'])){

return __error('token参数不存在');

}

//校验token

$data=JwtService::analysisJwt($data['token']);

if($data['message']=='Invalid signature encoding'){

return __error('token错误或已过期');

}

}else{

if(!isset($cookie['token'])){

jump('/Login/index');

}

//校验token

$data=JwtService::analysisJwt($cookie['token']);

if($data['message']=='Invalid signature encoding'){

jump('/Login/index');

}

}

lazy.png

4、jwt核心文件

lazy.png

namespace core\lib;

use \Firebase\JWT\JWT;

class JwtService

{

// 生成JWT

public static function createJwt($username='user123')

{

$time = time();

$key = conf::get('jwtKey','jwtservice');

$token = array(

'iss' => 'http://alframe2.local.com',// 签发人

'exp' => $time + 86400,// 过期时间(这里的有效期时间为1天)

'sub' => '主题内容',// 主题

'aud' => '受众内容',// 受众

'nbf' => $time,// 生效时间

'iat' => $time,// 签发时间

'jti' => 123,// 编号

// 额外自定义的数据

'data' => array('userName' => $username)

);

// 调用生成加密方法('Payloadn内容','加密的键',['加密算法'],['加密的可以'],['JWT的header头'])

$jwt = JWT::encode($token, $key);

return array ('data' => $jwt);

}

// 解析JWT

public static function analysisJwt($jwt)

{

try {

$key = conf::get('jwtKey','jwtservice');

// 调用解密方法('JWT内容','解密的键,和加密时的加密键一直','加密算法')

$decoded = JWT::decode($jwt, $key, array('HS256'));

return array ('message' => $decoded);

} catch (\Exception $exception) {

return array('message' => $exception->getMessage());

}

}

}

原创文章,作者:moonsec,如若转载,请注明出处:https://www.moonsec.com/archives/1365

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐