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

如何为Expo/React Native应用实现OpenSubtitles.com API认证?

OpenSubtitles.com API 安全认证方案(Expo/React Native)

核心思路

OpenSubtitles.com 支持 OAuth2 授权码流程,这是符合安全最佳实践的方案——用户无需向你的应用暴露账号密码,仅通过官方页面授权你的应用获取访问权限,最终你拿到的是短期有效的 JWT(Access Token)和用于刷新的 Refresh Token。

前置准备

  1. 前往 OpenSubtitles 开发者平台注册你的应用,获取 Client ID 和 Client Secret
  2. 配置应用的重定向 URI,Expo 环境下通常使用类似 exp://localhost:19000/--/auth/callback(需和代码中保持一致)

关键依赖

  • expo-auth-session:处理 OAuth2 授权的浏览器跳转、回调捕获
  • expo-secure-store:安全存储 Refresh Token(比普通 AsyncStorage 更安全,加密存储)
  • axios(或原生 fetch):发起 API 请求

实现步骤与代码示例

1. 配置 OAuth 授权参数

import * as AuthSession from 'expo-auth-session';

// OpenSubtitles OAuth 配置(端点需以官方文档为准)
const discovery = {
  authorizationEndpoint: 'https://www.opensubtitles.com/api/v1/login',
  tokenEndpoint: 'https://www.opensubtitles.com/api/v1/token',
};

const CLIENT_ID = '你的Client ID';
const REDIRECT_URI = 'exp://localhost:19000/--/auth/callback';

2. 发起授权请求

const startAuth = async () => {
  const result = await AuthSession.startAsync({
    authUrl: `${discovery.authorizationEndpoint}?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}`,
  });

  if (result.type === 'success') {
    await exchangeCodeForToken(result.params.code);
  } else {
    // 处理授权失败(用户取消、参数错误等)
    console.log('授权失败:', result);
  }
};

3. 用授权码换取 Token

import axios from 'axios';
import * as SecureStore from 'expo-secure-store';

const exchangeCodeForToken = async (code) => {
  try {
    const response = await axios.post(discovery.tokenEndpoint, {
      grant_type: 'authorization_code',
      code,
      client_id: CLIENT_ID,
      client_secret: '你的Client Secret',
      redirect_uri: REDIRECT_URI,
    });

    const { access_token, refresh_token, expires_in } = response.data;

    // 安全存储 Refresh Token
    await SecureStore.setItemAsync('opensubtitles_refresh_token', refresh_token);
    
    // Access Token 存内存即可,无需持久化
    global.opensubtitlesAccessToken = access_token;
    // 记录过期时间,提前触发刷新
    global.tokenExpiry = Date.now() + expires_in * 1000;
  } catch (error) {
    console.error('换取Token失败:', error);
  }
};

4. 刷新 Access Token

const refreshAccessToken = async () => {
  const refreshToken = await SecureStore.getItemAsync('opensubtitles_refresh_token');
  if (!refreshToken) return null;

  try {
    const response = await axios.post(discovery.tokenEndpoint, {
      grant_type: 'refresh_token',
      refresh_token: refreshToken,
      client_id: CLIENT_ID,
      client_secret: '你的Client Secret',
    });

    const { access_token, refresh_token, expires_in } = response.data;
    await SecureStore.setItemAsync('opensubtitles_refresh_token', refresh_token);
    global.opensubtitlesAccessToken = access_token;
    global.tokenExpiry = Date.now() + expires_in * 1000;
    return access_token;
  } catch (error) {
    // Refresh Token 失效,需重新引导用户授权
    console.error('刷新Token失败:', error);
    await SecureStore.deleteItemAsync('opensubtitles_refresh_token');
    return null;
  }
};

5. 发起带认证的 API 请求

const fetchSubtitles = async () => {
  // 检查 Token 是否即将过期,提前刷新
  if (Date.now() > global.tokenExpiry - 60 * 1000) {
    const newToken = await refreshAccessToken();
    if (!newToken) {
      // Token 刷新失败,引导用户重新授权
      startAuth();
      return;
    }
  }

  try {
    const response = await axios.get('https://www.opensubtitles.com/api/v1/subtitles', {
      headers: {
        'Api-Key': '你的应用API密钥',
        'Authorization': `Bearer ${global.opensubtitlesAccessToken}`
      },
      params: {
        // 按需添加请求参数
        query: '你的搜索关键词'
      }
    });
    return response.data;
  } catch (error) {
    console.error('API请求失败:', error);
  }
};

注意事项

  • 不要持久化 Access Token:Access Token 有效期短,存在内存即可,过期后用 Refresh Token 刷新
  • SecureStore 仅存 Refresh Token:Refresh Token 有效期长,必须加密存储,避免泄露
  • 异常处理要全面:比如 Refresh Token 失效、网络错误,需及时引导用户重新授权
  • 确认官方端点:上述代码中的授权和 Token 端点需以 OpenSubtitles 官方最新文档为准

内容的提问来源于stack exchange,提问作者l00mad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 06:02:54