引言

在现代移动应用开发中,身份验证与授权是关键环节。JSON Web Token(JWT)作为一种简洁、安全的跨系统身份验证解决方案,被广泛应用。本文将结合鸿蒙开发框架,详细讲解如何实现一个 JWT 生成工具类,帮助开发者在鸿蒙应用中高效处理身份验证相关功能。

技术背景

JWT 简介

JWT 由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。头部定义算法和令牌类型,载荷存放声明信息,签名用于验证令牌的完整性。

鸿蒙相关模块

  • @kit.UniversalKeystoreKit:用于密钥管理,本文中实现 HMAC-SHA256 签名时使用其生成和管理密钥。
  • @ohos.util:提供文本编码、Base64 编解码、UUID 生成等实用工具方法,助力 JWT 各部分的处理。

代码实现详解

整体结构

我们创建 JwtUtil 类,包含生成 JWT 的核心方法 generateJWT,以及辅助方法如解析过期时间 parseExpTime、字符串转 Uint8Array 的 StringToUint8Array、Base64URL 编码 base64UrlEncode、HMAC-SHA256 签名计算 hmacSha256 等。

关键方法解析

1. generateJWT - 生成完整 JWT
static async generateJWT(params: JwtParams): Promise<string> {  
    const claims: JwtClaims = {  
        iss: params.iss || 'picclife',  
        sub: params.sub || 'rbyt',  
        aud: params.aud || 'mp',  
        iat: Math.floor(Date.now() / 1000),  
        exp: JwtUtil.parseExpTime(params.expTime),  
        jti: JwtUtil.generateUUID(),  
        jsonData: params.jsonData || 'datas'  
    };  

    const header: string = JSON.stringify({ alg: 'HS256', typ: 'JWT' });  
    const payload: string = JSON.stringify(claims);  
    const secret: string = JwtUtil.encrypt(params.userToken, params.dynamicCode);  
    const message: string = `${JwtUtil.base64UrlEncode(header)}.${JwtUtil.base64UrlEncode(payload)}`;  
    const signature: string = await JwtUtil.hmacSha256(message, secret);  

    return `${JwtUtil.base64UrlEncode(header)}.${JwtUtil.base64UrlEncode(payload)}.${signature}`;  
}  

该方法首先构建 JWT 的载荷部分 claims,包含发行者 iss、主题 sub、受众 aud、签发时间 iat、过期时间 exp、唯一标识 jti 等信息。然后对头部和载荷进行 Base64URL 编码,最后结合加密后的密钥计算签名,拼接成完整的 JWT。

2. hmacSha256 - HMAC-SHA256 签名计算
static async hmacSha256(message: string, secret: string): Promise<string> {  
    const keyAlias: string = 'JWT_HMAC_KEY';  
    let handle: number = -1;  

    try {  
        // 1. 生成 HMAC 密钥  
        const properties: Array<huks.HuksParam> = [  
            { tag: huks.HuksTag.HUKS_TAG_ALGORITHM, value: huks.HuksKeyAlg.HUKS_ALG_HMAC },  
            { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256 },  
            { tag: huks.HuksTag.HUKS_TAG_PURPOSE, value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_MAC },  
            { tag: huks.HuksTag.HUKS_TAG_DIGEST, value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256 }  
        ];  
        await huks.generateKeyItem(keyAlias, { properties });  

        // 2. 初始化 HMAC 会话  
        const options: huks.HuksOptions = {  
            properties,  
            inData: JwtUtil.StringToUint8Array(secret)  
        };  
        const initResult: huks.HuksSessionHandle = await huks.initSession(keyAlias, options);  
        handle = initResult.handle;  

        // 3. 计算签名  
        const computeResult: huks.HuksReturnResult = await huks.finishSession(handle, {  
            inData: JwtUtil.StringToUint8Array(message)  
        });  

        // 4. 销毁密钥  
        await huks.deleteKeyItem(keyAlias);  

        return JwtUtil.Uint8ArrayToHex(computeResult.outData as Uint8Array);  
    } catch (error) {  
        console.error('HMAC-SHA256 错误:', error);  
        throw new Error('签名失败');  
    } finally {  
        if (handle !== -1) {  
            // await huks.abortSession(handle);  
        }  
    }  
}  

此方法通过鸿蒙的 UniversalKeystoreKit 生成 HMAC 密钥,初始化会话,传入待签名消息和密钥进行签名计算,最后销毁密钥,确保安全。通过 Uint8ArrayToHex 将签名结果转换为十六进制字符串。

3. base64UrlEncode - Base64URL 编码
static base64UrlEncode(str: string): string {  
    const uint8Array: Uint8Array = JwtUtil.StringToUint8Array(str);  
    const base64Helper: util.Base64Helper = new util.Base64Helper();  
    const base64Bytes: Uint8Array = base64Helper.encodeSync(uint8Array);  
    const decoder: util.TextDecoder = new util.TextDecoder();  
    const base64String: string = decoder.decode(base64Bytes);  
    return base64String.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');  
}  

先将字符串转换为 Uint8Array,利用鸿蒙 Base64Helper 进行 Base64 编码,再将编码结果转换为字符串,最后替换字符满足 Base64URL 编码规范。

总结

通过本文的代码实现,我们在鸿蒙应用中构建了一个功能完整的 JWT 生成工具类。从 JWT 各部分的构建,到利用鸿蒙模块实现安全的签名计算,每个环节都紧密结合鸿蒙开发特性。开发者可以基于此工具类,快速在鸿蒙应用中集成 JWT 相关的身份验证功能,同时也可根据实际业务需求,对代码进行扩展和优化,如完善错误处理、优化日志记录等。希望本文能为鸿蒙开发者在身份验证开发场景中提供有力的参考。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐