我需要使用此 cURL 发出 API 请求
curl -L -i -X PUT –cert ./[device_cert].pem –key ./[device_cert_private_key].pem -H 'Content-Type: application/json' -H 'Content-Encoding: utf-8' -d '{"registrationId": "[registration_id]"}' https://global.azure-devices-provisioning.net/[ID_Scope]/registrations/[registration_id]/register?api-version=2021-06-01
我把它转换成axios,看起来像这样
const data = {
registrationId: registrationId,
};
const cert = await RNFS.readFile(certificatePath, 'utf8');
const key = await RNFS.readFile(keyPath, 'utf8');
console.log('cert', cert);
console.log('key', key);
try {
const httpsAgent = new https.Agent({
cert: cert,
key: key,
});
console.log('httpsAgent', httpsAgent);
const response = await axios({
method: 'PUT',
url: `https://global.azure-devices-provisioning.net/${scopeId}/registrations/${registrationId}/register?api-version=2021-06-01`,
data: data,
httpsAgent: httpsAgent,
headers: {
'Content-Type': 'application/json',
'Content-Encoding': 'utf-8',
},
});
return response.data;
} catch (err) {
console.log('err', err);
return err;
}
在节点中,我们有名为
https
的 API,它提供 Agent
方法来为 API 请求添加证书和私有:
const httpsAgent = new https.Agent({cert:cert,key:key})
但是React Native不支持
https
。
所以我尝试了多个软件包,例如rn-nodeifynode-libs-react-nativereact-native-ssl-pinning 我无法使用 nodejs-mobile-react-native,因为这个包的应用程序大小增加了很多。 如何在 React Native 中使用
https.Agent
?
谢谢你
React Native 本身并不支持 Node.js 中的
https.Agent
,但您可以通过使用支持证书固定或自定义 SSL 配置的库来实现类似的功能。我们将使用包 axios
、react-native-ssl-pinning
和 react-native-fs
。
请参阅此SO了解
和React Native集成。我使用 react-native-fetch 或 axios 包。https.Agent
import React, { useEffect } from 'react';
import { Image, StyleSheet, Platform, View, Text } from 'react-native';
import axios from 'axios';
import { HelloWave } from '@/components/HelloWave';
import ParallaxScrollView from '@/components/ParallaxScrollView';
import { ThemedText } from '@/components/ThemedText';
import { ThemedView } from '@/components/ThemedView';
const deviceCert = `-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----`;
const devicePrivateKey = `-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----`;
const registrationId = '[registration_id]';
const idScope = '[ID_Scope]';
export default function HomeScreen() {
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.put(
`https://global.azure-devices-provisioning.net/${idScope}/registrations/${registrationId}/register?api-version=2021-06-01`,
{
registrationId: registrationId
},
{
headers: {
'Content-Type': 'application/json',
'Content-Encoding': 'utf-8',
// Note: Certificates and keys are not directly supported by axios config
},
timeout: 3000, // 3 seconds timeout
}
);
console.log(response.data);
} catch (error) {
console.error(error);
}
};
fetchData();
}, []);
return (
<ParallaxScrollView
headerBackgroundColor={{ light: '#A1CEDC', dark: '#1D3D47' }}
headerImage={
<Image
source={require('@/assets/images/partial-react-logo.png')}
style={styles.reactLogo}
/>
}>
<ThemedView style={styles.titleContainer}>
<ThemedText type="title">Welcome!</ThemedText>
<HelloWave />
</ThemedView>
<ThemedView style={styles.stepContainer}>
<ThemedText type="subtitle">Step 1: Try it</ThemedText>
<ThemedText>
Edit <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> to see changes.
Press{' '}
<ThemedText type="defaultSemiBold">
{Platform.select({ ios: 'cmd + d', android: 'cmd + m' })}
</ThemedText>{' '}
to open developer tools.
</ThemedText>
</ThemedView>
<ThemedView style={styles.stepContainer}>
<ThemedText type="subtitle">Step 2: Explore</ThemedText>
<ThemedText>
Tap the Explore tab to learn more about what's included in this starter app.
</ThemedText>
</ThemedView>
<ThemedView style={styles.stepContainer}>
<ThemedText type="subtitle">Step 3: Get a fresh start</ThemedText>
<ThemedText>
When you're ready, run{' '}
<ThemedText type="defaultSemiBold">npm run reset-project</ThemedText> to get a fresh{' '}
<ThemedText type="defaultSemiBold">app</ThemedText> directory. This will move the current{' '}
<ThemedText type="defaultSemiBold">app</ThemedText> to{' '}
<ThemedText type="defaultSemiBold">app-example</ThemedText>.
</ThemedText>
</ThemedView>
</ParallaxScrollView>
);
}
const styles = StyleSheet.create({
titleContainer: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
},
stepContainer: {
gap: 8,
marginBottom: 8,
},
reactLogo: {
height: 178,
width: 290,
bottom: 0,
left: 0,
position: 'absolute',
},
});
使用
react-native-axios
时,您可能会面临 SSL 固定问题。 GitHub 问题 提供了有关将 React Native SSL pinning 与 Axios 库结合使用的指南。
与react-native-fetch、react-native-fs、react-native-ssl-pinning一起使用
const handleRequest = async () => {
const certificatePath = RNFS.DocumentDirectoryPath + '/device_cert.pem';
const keyPath = RNFS.DocumentDirectoryPath + '/device_cert_private_key.pem';
const registrationId = 'your_registration_id_here';
const scopeId = 'your_scope_id_here';
try {
const cert = await RNFS.readFile(certificatePath, 'utf8');
const key = await RNFS.readFile(keyPath, 'utf8');
const response = await fetch(`https://global.azure-devices-provisioning.net/${scopeId}/registrations/${registrationId}/register?api-version=2021-06-01`, {
method: 'PUT',
body: JSON.stringify({ registrationId: registrationId }),
headers: {
'Content-Type': 'application/json',
'Content-Encoding': 'utf-8',
},
});
// Handle response
const json = await response.json();
console.log('Response:', json);
} catch (error) {
console.error('Request failed', error);
}
};
useEffect(() => {
handleRequest();
}, []);
return (
<View style={styles.container}>
<Text>Check console for results</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});