PHP JWT CI 框架

guyun發表於2019-04-15

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 協議》,轉載必須註明作者和本文連結

相關文章