Initial commit: Expo app with Better Auth integration
- Complete Expo React Native app setup with TypeScript - Better Auth authentication system integration - Secure storage implementation for session tokens - Authentication flow with login/logout functionality - API client configuration for backend communication - Responsive UI components with themed styling - Expo Router navigation setup - Development configuration and scripts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
162
utils/cookie-encoding.ts
Normal file
162
utils/cookie-encoding.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Cookie编码处理工具
|
||||
* 解决特殊字符在Cookie中的编码问题
|
||||
*/
|
||||
|
||||
/**
|
||||
* 安全编码Cookie值
|
||||
* 使用encodeURIComponent确保特殊字符正确编码
|
||||
*
|
||||
* @param value 原始值
|
||||
* @returns 编码后的值
|
||||
*/
|
||||
export function encodeCookieValue(value: string): string {
|
||||
if (!value) return '';
|
||||
|
||||
try {
|
||||
// 使用encodeURIComponent编码所有特殊字符
|
||||
return encodeURIComponent(value);
|
||||
} catch (error) {
|
||||
console.error('Cookie值编码失败:', error);
|
||||
return value; // 编码失败时返回原值
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全解码Cookie值
|
||||
* 使用decodeURIComponent解码编码的值
|
||||
*
|
||||
* @param encodedValue 编码后的值
|
||||
* @returns 解码后的原始值
|
||||
*/
|
||||
export function decodeCookieValue(encodedValue: string): string {
|
||||
if (!encodedValue) return '';
|
||||
|
||||
try {
|
||||
// 使用decodeURIComponent解码
|
||||
return decodeURIComponent(encodedValue);
|
||||
} catch (error) {
|
||||
console.error('Cookie值解码失败:', error);
|
||||
// 解码失败时,可能值已经未编码,返回原值
|
||||
return encodedValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量编码Cookie对象中的所有值
|
||||
*
|
||||
* @param cookieObj Cookie对象 {key: value}
|
||||
* @returns 编码后的Cookie对象
|
||||
*/
|
||||
export function encodeCookieObject(cookieObj: Record<string, string>): Record<string, string> {
|
||||
const encoded: Record<string, string> = {};
|
||||
|
||||
for (const [key, value] of Object.entries(cookieObj)) {
|
||||
encoded[key] = encodeCookieValue(value);
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量解码Cookie对象中的所有值
|
||||
*
|
||||
* @param encodedCookieObj 编码的Cookie对象
|
||||
* @returns 解码后的Cookie对象
|
||||
*/
|
||||
export function decodeCookieObject(encodedCookieObj: Record<string, string>): Record<string, string> {
|
||||
const decoded: Record<string, string> = {};
|
||||
|
||||
for (const [key, value] of Object.entries(encodedCookieObj)) {
|
||||
decoded[key] = decodeCookieValue(value);
|
||||
}
|
||||
|
||||
return decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全解析包含编码值的Cookie字符串
|
||||
*
|
||||
* @param cookieString Cookie字符串
|
||||
* @returns 解析后的Cookie对象
|
||||
*/
|
||||
export function parseEncodedCookieString(cookieString: string): Record<string, string> {
|
||||
if (!cookieString) return {};
|
||||
|
||||
const cookies: Record<string, string> = {};
|
||||
|
||||
// 分割多个Cookie对
|
||||
const cookiePairs = cookieString.split(';').map(pair => pair.trim());
|
||||
|
||||
for (const pair of cookiePairs) {
|
||||
if (!pair) continue;
|
||||
|
||||
const [key, ...valueParts] = pair.split('=');
|
||||
if (!key) continue;
|
||||
|
||||
const value = valueParts.join('=');
|
||||
cookies[key] = decodeCookieValue(value);
|
||||
}
|
||||
|
||||
return cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建包含编码值的Cookie字符串
|
||||
*
|
||||
* @param cookieObj Cookie对象
|
||||
* @returns 编码后的Cookie字符串
|
||||
*/
|
||||
export function createEncodedCookieString(cookieObj: Record<string, string>): string {
|
||||
const encodedPairs: string[] = [];
|
||||
|
||||
for (const [key, value] of Object.entries(cookieObj)) {
|
||||
const encodedValue = encodeCookieValue(value);
|
||||
encodedPairs.push(`${key}=${encodedValue}`);
|
||||
}
|
||||
|
||||
return encodedPairs.join('; ');
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查字符串是否包含特殊字符
|
||||
*
|
||||
* @param value 要检查的字符串
|
||||
* @returns 是否包含需要编码的字符
|
||||
*/
|
||||
export function hasSpecialChars(value: string): boolean {
|
||||
// 检查是否包含需要编码的特殊字符
|
||||
const specialChars = /[^\w\-._~!$&'()*+,;=:@\/]/;
|
||||
return specialChars.test(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 智能编码:仅对包含特殊字符的值进行编码
|
||||
*
|
||||
* @param value 要编码的值
|
||||
* @returns 编码后的值
|
||||
*/
|
||||
export function smartEncodeCookieValue(value: string): string {
|
||||
if (!value) return '';
|
||||
|
||||
// 如果包含特殊字符则编码,否则返回原值
|
||||
return hasSpecialChars(value) ? encodeCookieValue(value) : value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 智能解码:尝试解码,失败则返回原值
|
||||
*
|
||||
* @param encodedValue 可能编码的值
|
||||
* @returns 解码后的值
|
||||
*/
|
||||
export function smartDecodeCookieValue(encodedValue: string): string {
|
||||
if (!encodedValue) return '';
|
||||
|
||||
// 尝试解码,如果解码后的值与原值相同,可能说明没有编码过
|
||||
try {
|
||||
const decoded = decodeCookieValue(encodedValue);
|
||||
return decoded;
|
||||
} catch (error) {
|
||||
return encodedValue;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user