composer.json
"require": {
...
"nesbot/carbon": "^1.25",
"firebase/php-jwt": "^5.0"
},
/*** CI框架 helper自建檔案 **************************/
/**
* 校驗jwt是否有效
* @param string $jwt
* @return array|bool 有效則返回 jwt 陣列,無效返回 false
*/
function jwt_verify($jwt)
{
$decoded = null;
try {
// config_item('encryption_key') CI框架config配置的隨機字串
$decoded = \Firebase\JWT\JWT::decode($jwt, config_item('encryption_key'), array('HS256'));
} catch (\Firebase\JWT\ExpiredException $e) {
// 過期
return false;
} catch (\Exception $e) {
return false;
}
/*
* NOTE: This will now be an object instead of an associative array. To get
* an associative array, you will need to cast it as such:
*/
return (array) $decoded;
}
/**
* 學習文件
* https://jwt.io/
* https://github.com/firebase/php-jwts
*
* 生成jwt字串
* @param array $payload 要在jwt中攜帶的資訊
* @param int $exp 時間戳:過期時間;payload 和 exp 均不設定則永不過期
* @return string 生成的jwt字串
*/
function jwt_encode($payload = [], $exp = 0)
{
/* jwt標準中註冊的宣告
array(
"iss" => "http://example.org", // jwt簽發者
"sub" => "", // jwt面向的使用者
"aud" => "http://example.com", // jwt接收者
"iat" => 1356999524, // jwt簽發時間
"nbf" => 1357000000, // jwt生效時間,在該時間前一直無效
"exp" => 1520000000, // jwt的過期時間,這個過期時間必須要大於簽發時間
"jti" => '', // jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。
);
*/
$now = time();
$_payload = array(
// "iat" => 1520000000,
// "nbf" => 1520000000,
"exp" => $now + 3600,
);
$payload = array_merge($_payload, $payload);
if ($exp > 0) {
$payload['exp'] = $exp;
}
// 簽發伺服器和驗證伺服器有時間差時設定,不要設定太大
// JWT::$leeway = 60;
// config_item('encryption_key') CI框架config配置的隨機字串
$jwt = \Firebase\JWT\JWT::encode($payload, config_item('encryption_key'));
return $jwt;
}
function check_login_status()
{
$CI = &get_instance();
// config_item('jwt_user_info_cookie_name') CI框架config配置的隨機字串
$jwt_user_info = $CI->input->cookie(config_item('jwt_user_info_cookie_name'));
$jwt = jwt_verify($jwt_user_info);
if(isset($jwt["user"])){
//相容新SSO系統jwt
$user = (array)$jwt["user"];
$user_info = [
"username"=>$user["XXX"],
"user_id"=>$user["id"],
"ip"=>$user["ip"],
];
return $user_info;
}
return $jwt;
}
/***********************************************************
* 退出
***********************************************************/
public function logout()
{
$cookie_name = config_item('jwt_user_info_cookie_name'); // 鍵名
delete_cookie($cookie_name);
getJsonInstance()->code(0)->msg('退出成功')->out();
}
/*************************************************************
* 寫入登入cookie
* @param $cookie_data
* @param bool $keep_30 記住密碼30天
* @return string
**************************************************************/
private function set_login_cookie($cookie_data, $keep_30 = false)
{
// 儲存 user_info 的 cookie 鍵名
$cookie_name = config_item('jwt_user_info_cookie_name');
$now = time();
if ($keep_30) {
// 30天免密登入
$exp = 3600 * 24 * 30;
$token = jwt_encode($cookie_data, $now + $exp);
// 設定 cookie ,有效期同token有效期
// CI框架的set_cookie方法傳的exp是cookie有效時長,不是失效時間
set_cookie($cookie_name, $token, $exp);
} else {
// 普通登入
$exp = 3600 * 24;
$token = jwt_encode($cookie_data, $now + $exp);
// 設定 cookie ,有效期為會話有效期
set_cookie($cookie_name, $token, 0);
}
return $token;
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結