React Native Noob问题:如何在React Native中使用JS库
我认为使用包装NPM的JS库非常简单,但我没有运气。任何建议将不胜感激。这些是我采取的步骤。
- 我安装了一个图书馆:
npm安装hotp-totp;
- 然后,我为自定义组件创建了一个文件:
//otp.js
import React from 'react';
import {
Text,
View,
} from 'react-native';
import totp from 'hotp-totp';
const OTP = () => {
let secret = 'MNWRM734ZIOEZYEYCAW4I6EX';
let token = totp(secret);
return (
<View>
<Text>
{ token }
</Text>
</View>
)
}
export default OTP
然后,我导入此组件并尝试渲染:
//App.js
import OTP from './otp.js';
const App: () => Node = () => {
return (
<SafeAreaView >
<ScrollView
contentInsetAdjustmentBehavior="automatic">
<OTP />
</ScrollView>
</SafeAreaView>
);
};
然后尝试在Android设备上运行时,我会得到以下错误跟踪:
ERROR TypeError: (0, _hotpTotp.default) is not a function. (In '(0, _hotpTotp.default)(secret)', '(0, _hotpTotp.default)' is an instance of Object)
This error is located at:
in OTP (at App.js:74)
in RCTView (at View.js:32)
in View (at ScrollView.js:1682)
in RCTScrollView (at ScrollView.js:1800)
in ScrollView (at ScrollView.js:1826)
in ScrollView (at App.js:69)
in RCTView (at View.js:32)
in View (at SafeAreaView.js:41)
in SafeAreaView (at App.js:67)
in App (at renderApplication.js:50)
in RCTView (at View.js:32)
in View (at AppContainer.js:92)
in RCTView (at View.js:32)
in View (at AppContainer.js:119)
in AppContainer (at renderApplication.js:43)
in otp(RootComponent) (at renderApplication.js:60)
ERROR TypeError: (0, _hotpTotp.default) is not a function. (In '(0, _hotpTotp.default)(secret)', '(0, _hotpTotp.default)' is an instance of Object)
库HOTP-TOTP非常简单,我将其包括在下面供参考。
/* node_modules/hotp-totp/index.js */
import base32 from 'thirty-two';
// Time-based OTP
const totp = async (secret) => {
return hotp( secret, Math.floor( +new Date() / 30000 ) );
}
// HMAC-based OTP
const hotp = async (secret, counter) => {
// Uint8Array(20)
const hmac = async (secret, counter) => {
const keyData = Uint8Array.from(base32.decode(secret));
const key = await crypto.subtle.importKey(
'raw',
keyData,
{ name: 'HMAC', hash: { name: 'SHA-1' } },
false,
['sign']
);
return new Uint8Array(
await crypto.subtle.sign('HMAC', key, padCounter(counter))
);
}
// Uint8Array(8)
const padCounter = (counter) => {
const pairs = counter.toString(16).padStart(16, '0').match(/..?/g);
const array = pairs.map(v => parseInt(v, 16));
return Uint8Array.from( array );
}
// Number
function truncate(hs) {
const offset = hs[19] & 0b1111;
return ((hs[offset] & 0x7f) << 24) | (hs[offset + 1] << 16) | (hs[offset + 2] << 8) | hs[offset + 3];
}
// HOTP(K, C) = truncate(HMAC(K, C))
const num = truncate( await hmac(secret, counter) );
// return 6 digits, padded with leading zeros
return num.toString().padStart(6, '0').slice(-6);
}
/**/
export default {
hotp,
totp,
}
任何帮助将不胜感激。
I thought it would be pretty straightforward to use a js library that is packaged with npm but I'm not having any luck. Any suggestions would be greatly appreciated. These are the steps I took.
- I installed a library with:
npm install hotp-totp;
- I then created a file for a custom component:
//otp.js
import React from 'react';
import {
Text,
View,
} from 'react-native';
import totp from 'hotp-totp';
const OTP = () => {
let secret = 'MNWRM734ZIOEZYEYCAW4I6EX';
let token = totp(secret);
return (
<View>
<Text>
{ token }
</Text>
</View>
)
}
export default OTP
I then import this component and attempt to render:
//App.js
import OTP from './otp.js';
const App: () => Node = () => {
return (
<SafeAreaView >
<ScrollView
contentInsetAdjustmentBehavior="automatic">
<OTP />
</ScrollView>
</SafeAreaView>
);
};
When I then try to run on my Android device I get the following error trace:
ERROR TypeError: (0, _hotpTotp.default) is not a function. (In '(0, _hotpTotp.default)(secret)', '(0, _hotpTotp.default)' is an instance of Object)
This error is located at:
in OTP (at App.js:74)
in RCTView (at View.js:32)
in View (at ScrollView.js:1682)
in RCTScrollView (at ScrollView.js:1800)
in ScrollView (at ScrollView.js:1826)
in ScrollView (at App.js:69)
in RCTView (at View.js:32)
in View (at SafeAreaView.js:41)
in SafeAreaView (at App.js:67)
in App (at renderApplication.js:50)
in RCTView (at View.js:32)
in View (at AppContainer.js:92)
in RCTView (at View.js:32)
in View (at AppContainer.js:119)
in AppContainer (at renderApplication.js:43)
in otp(RootComponent) (at renderApplication.js:60)
ERROR TypeError: (0, _hotpTotp.default) is not a function. (In '(0, _hotpTotp.default)(secret)', '(0, _hotpTotp.default)' is an instance of Object)
The library hotp-totp is pretty straightforward and I include it below for reference.
/* node_modules/hotp-totp/index.js */
import base32 from 'thirty-two';
// Time-based OTP
const totp = async (secret) => {
return hotp( secret, Math.floor( +new Date() / 30000 ) );
}
// HMAC-based OTP
const hotp = async (secret, counter) => {
// Uint8Array(20)
const hmac = async (secret, counter) => {
const keyData = Uint8Array.from(base32.decode(secret));
const key = await crypto.subtle.importKey(
'raw',
keyData,
{ name: 'HMAC', hash: { name: 'SHA-1' } },
false,
['sign']
);
return new Uint8Array(
await crypto.subtle.sign('HMAC', key, padCounter(counter))
);
}
// Uint8Array(8)
const padCounter = (counter) => {
const pairs = counter.toString(16).padStart(16, '0').match(/..?/g);
const array = pairs.map(v => parseInt(v, 16));
return Uint8Array.from( array );
}
// Number
function truncate(hs) {
const offset = hs[19] & 0b1111;
return ((hs[offset] & 0x7f) << 24) | (hs[offset + 1] << 16) | (hs[offset + 2] << 8) | hs[offset + 3];
}
// HOTP(K, C) = truncate(HMAC(K, C))
const num = truncate( await hmac(secret, counter) );
// return 6 digits, padded with leading zeros
return num.toString().padStart(6, '0').slice(-6);
}
/**/
export default {
hotp,
totp,
}
Any help would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要这样的导入TOTP,
可以阅读有关它的更多信息在这里
You need to import totp like this
You can read more about it here