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

Expo托管React Native应用如何转换Stytch OTP的cURL请求

解答

首先你不能直接把这段带-u 'MY-SECRET-YO'鉴权参数的请求直接写在React Native客户端代码里,有两个致命问题:

  • 该参数是Stytch的服务端秘钥,客户端属于公开可反编译的环境,硬编码秘钥会直接导致你的Stytch账号被盗用,产生资损
  • Stytch的服务端API默认禁止跨域客户端直接调用,直接请求会触发CORS拦截,根本无法正常返回结果

正确的实现方式有两种,按需选择即可:


方案1:使用Stytch官方React Native SDK(推荐,无需自建后端)

直接使用官方维护的客户端SDK,走公开客户端鉴权流程,不需要暴露服务端秘钥,是官方推荐的客户端接入方式:

  1. 先安装SDK依赖
    npm install @stytch/react-native
    # 或者yarn add @stytch/react-native
    
  2. 在应用入口初始化SDK,使用你项目的公开public_token(注意是公开客户端令牌,不是服务端秘钥)
    import { StytchProvider, StytchClient } from '@stytch/react-native';
    
    const stytchClient = new StytchClient('public-token-你的项目公开令牌');
    
    export default function App() {
      return (
        <StytchProvider stytch={stytchClient}>
          {/* 你的应用根组件 */}
        </StytchProvider>
      )
    }
    
  3. 在发送验证码的页面直接调用SDK提供的发送短信OTP方法即可
    const handleSendOtp = async (phoneNumber) => {
      try {
        // phoneNumber必须是E.164格式,例如+8613xxxxxxxxx
        const resp = await stytchClient.otps.sms.send({
          phone_number: phoneNumber
        })
        // 发送成功,跳转到验证码输入页
        console.log('OTP发送成功', resp)
      } catch (err) {
        console.error('发送失败', err)
      }
    }
    

后续验证码校验、会话管理SDK都有封装好的方法,直接调用即可,不需要自己处理鉴权逻辑。


方案2:自建后端代理接口

如果你不想用官方SDK,需要自己搭一层后端服务做请求代理,所有带服务端秘钥的请求都在后端完成:

  1. React Native客户端只负责把用户输入的手机号传给你自己的后端接口,不要带任何Stytch秘钥
    // RN客户端请求示例
    const sendOtp = async (phoneNumber) => {
      const resp = await fetch('https://你的业务域名/api/auth/send-sms-otp', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ phone_number: phoneNumber })
      })
      const data = await resp.json()
      if (!resp.ok) throw new Error(data.message || '发送失败')
      return data
    }
    
  2. 你的后端收到请求后,校验参数合法性,再构造带Basic Auth鉴权的请求转发给Stytch接口,以Node.js Express服务为例:
    const express = require('express')
    const axios = require('axios')
    const app = express()
    app.use(express.json())
    
    // 从环境变量读取Stytch凭证,绝对不要硬编码在代码里
    const STYTCH_PROJECT_ID = process.env.STYTCH_PROJECT_ID
    const STYTCH_SECRET = process.env.STYTCH_SECRET
    
    app.post('/api/auth/send-sms-otp', async (req, res) => {
      const { phone_number } = req.body
      // 先校验手机号格式,必须符合E.164规范
      if (!/^\+[1-9]\d{1,14}$/.test(phone_number || '')) {
        return res.status(400).json({ message: '手机号格式错误' })
      }
    
      try {
        // 对应原cURL的-u鉴权参数:Basic Auth的用户名为项目ID,密码为服务端秘钥
        const stytchResp = await axios.post(
          'https://test.stytch.com/v1/otps/sms/send',
          { phone_number },
          {
            auth: { username: STYTCH_PROJECT_ID, password: STYTCH_SECRET },
            headers: { 'Content-Type': 'application/json' }
          }
        )
        // 仅返回必要字段给客户端,不要透传Stytch返回的全量敏感数据
        return res.json({ success: true, request_id: stytchResp.data.request_id })
      } catch (err) {
        console.error('调用Stytch失败', err.response?.data || err.message)
        return res.status(500).json({ message: '验证码发送失败,请稍后重试' })
      }
    })
    
    app.listen(3000)
    

后续的OTP校验逻辑同理:客户端把用户输入的验证码传给后端,后端调用Stytch的校验接口,验证通过后给客户端下发你自己业务的登录凭证即可。

补充说明:你提供的cURL示例里-u 'MY-SECRET-YO'是简化写法,实际Stytch的Basic Auth要求传入项目ID:秘钥拼接后的凭证,单独传秘钥会报鉴权失败。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:30:08