相当于 React Native 中的 `https.agent`

问题描述 投票:0回答:1

我需要使用此 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
? 谢谢你

android ios react-native https azure-iot-hub
1个回答
0
投票

React Native 本身并不支持 Node.js 中的

https.Agent
,但您可以通过使用支持证书固定或自定义 SSL 配置的库来实现类似的功能。我们将使用包
axios
react-native-ssl-pinning
react-native-fs

请参阅此SO了解

https.Agent
和React Native集成。我使用 react-native-fetchaxios 包。

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',

},

});

enter image description here

使用

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',
  },
});
© www.soinside.com 2019 - 2024. All rights reserved.