You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native/Expo中Basic Authorization的btoa()函数替代困惑

Fixing Base64 Mismatch Between Browser btoa() and React Native/Expo for Basic Auth

Hey there! I totally get the frustration when something that worked smoothly in Cordova (and browsers) breaks in React Native/Expo—let’s break down why your Base64 results don’t match, and fix that Basic Auth setup once and for all.

The Core Difference: btoa() vs. Most RN/Expo Base64 Libraries

The browser’s btoa() function encodes strings using Latin-1 (ISO-8859-1) character encoding. But almost all Base64 utilities in React Native/Expo (like Expo Crypto or third-party libraries such as base64-js) default to UTF-8 encoding. This is the root cause of your mismatched results!

If your credentials (username/password) include non-ASCII characters (like accents, emojis, or non-Latin scripts), Latin-1 and UTF-8 will convert those characters to completely different byte sequences—and thus different Base64 outputs. Even if you’re using ASCII-only credentials right now, fixing this properly avoids edge cases later.

Expo has a built-in expo-crypto module that we can use to replicate btoa()’s exact behavior by first converting our string to a Latin-1 byte array:

import * as Crypto from 'expo-crypto';

// Replicates browser's btoa() behavior in React Native/Expo
function btoaRN(str) {
  // Convert string to a Latin-1 encoded Uint8Array
  const latin1Bytes = new Uint8Array(str.length);
  for (let i = 0; i < str.length; i++) {
    // Latin-1 only uses values 0-255; mod 256 ensures we stay within that range
    latin1Bytes[i] = str.charCodeAt(i) % 256;
  }
  // Encode the byte array to Base64
  return Crypto.encodeBase64String(latin1Bytes);
}

// Use it for Basic Auth
const username = "your-username";
const password = "your-password";
const credentials = `${username}:${password}`;
const basicAuthHeader = `Basic ${btoaRN(credentials)}`;

Solution 2: Use Third-Party base64-js Library

If you prefer using a standalone library, install base64-js first (npm install base64-js or yarn add base64-js), then use this approach:

import { encode } from 'base64-js';

function btoaRN(str) {
  const latin1Bytes = new Uint8Array(str.length);
  for (let i = 0; i < str.length; i++) {
    latin1Bytes[i] = str.charCodeAt(i) % 256;
  }
  return encode(latin1Bytes);
}

// Same Basic Auth usage as above
const credentials = `${username}:${password}`;
const basicAuthHeader = `Basic ${btoaRN(credentials)}`;

How to Verify It Works

Test with a string that has non-ASCII characters to confirm. For example:

  • Browser btoa("test:é") returns dGVzdDpp
  • Using our btoaRN() function should return the exact same string, whereas a UTF-8-based Base64 encode would return dGVzdDppw6E= (which is incorrect for Basic Auth).

Why This Matters for Basic Auth

HTTP Basic Auth (per RFC 7617) explicitly requires that the username:password string is encoded using Latin-1. Even if your current credentials are ASCII-only, following this spec ensures your code works for all valid credential formats down the line.

内容的提问来源于stack exchange,提问作者Ferenc Dobó

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:31:55