将NodeJS后端secure:true的Cookie适配到Expo React Native应用
1. 后端配置HTTPS
首先要给你的Node.js Express后端启用HTTPS,这是secure: true Cookie生效的核心前提:
生成SSL证书
- 开发环境可通过OpenSSL生成自签证书:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes - 生产环境需从正规CA机构(如Let’s Encrypt)获取可信证书。
修改Express服务器配置
替换原有HTTP服务器为HTTPS服务器,同时修正session和CORS配置:
const https = require('https'); const fs = require('fs'); const express = require('express'); const session = require('express-session'); const passport = require('passport'); const cors = require('cors'); const app = express(); // CORS必须允许凭证和匹配前端Origin app.use(cors({ origin: process.env.NODE_ENV === 'production' ? 'https://your-production-frontend.com' : 'exp://your-expo-dev-ip:19000', // 替换为你的Expo开发地址 credentials: true })); // Session配置保持secure: true app.use(session({ secret: 'your-strong-secret-key', resave: false, saveUninitialized: false, cookie: { secure: true, httpOnly: true, sameSite: process.env.NODE_ENV === 'production' ? 'lax' : 'none', // 跨域开发场景设为none maxAge: 24 * 60 * 60 * 1000 } })); app.use(passport.initialize()); app.use(passport.session()); // 你的路由、Passport认证逻辑等... // 启动HTTPS服务器 const sslOptions = { key: fs.readFileSync('./key.pem'), cert: fs.readFileSync('./cert.pem') }; https.createServer(sslOptions, app).listen(443, () => { console.log('HTTPS server running on port 443'); });
2. React Native(Expo)端适配
确保请求携带Cookie
无论使用fetch还是axios,必须开启凭证携带配置:
- 使用fetch:
const handleLogin = async (username, password) => { try { const res = await fetch('https://your-backend-domain.com/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }), credentials: 'include' // 关键:携带会话Cookie }); const data = await res.json(); // 处理登录结果 } catch (err) { console.error('Login failed:', err); } }; - 使用axios:
import axios from 'axios'; const apiClient = axios.create({ baseURL: 'https://your-backend-domain.com', withCredentials: true // 关键:自动携带Cookie }); const handleLogin = async (username, password) => { try { const res = await apiClient.post('/login', { username, password }); // 处理结果 } catch (err) { console.error('Login failed:', err); } };
开发环境处理自签证书信任问题
React Native默认不信任自签证书,可通过以下两种方式解决:
用ngrok暴露本地HTTPS服务
执行命令将本地HTTPS服务转发到公网(自带可信证书):ngrok http 443直接使用ngrok提供的
https://xxx.ngrok.io作为后端地址,RN即可正常接收Cookie。配置RN信任自签证书
Android:在
android/app/src/main/res/xml创建network_security_config.xml:<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">your-local-ip</domain> <!-- 替换成本地IP --> <trust-anchors> <certificates src="@raw/your_cert_name" /> <!-- 将自签cert.pem转为raw资源 --> </trust-anchors> </domain-config> </network-security-config>再在
AndroidManifest.xml的application标签添加android:networkSecurityConfig="@xml/network_security_config"。iOS:在
Info.plist中添加例外域名:<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>your-local-ip</key> <!-- 替换成本地IP --> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <false/> <key>NSTemporaryExceptionMinimumTLSVersion</key> <string>TLSv1.2</string> </dict> </dict> </dict>
3. 验证Cookie有效性
可在RN中打印请求响应头,确认set-cookie字段是否存在,后续请求是否自动携带connect.sid(默认session Cookie名)。
内容的提问来源于stack exchange,提问作者Loick Tanvez
相关产品推荐
相关产品推荐

