
मेरे चैनल डिमका रेकटिवनी के ग्राहकों के बीच सबसे अधिक अनुरोधित विषयों में से एक है रिएक्ट नेटिव एप्लिकेशन में प्रमाणीकरण और प्राधिकरण। इसलिए, मैंने इस मुद्दे को एक अलग लालसा के साथ संबोधित करने का फैसला किया और इससे पहले कि हम कोडिंग शुरू करें, प्रमाणीकरण / प्राधिकरण की परिभाषा से निपटना आवश्यक है।
प्रमाणीकरण
यह विषय के पत्राचार की जांच है और वह जिसके लिए वह कुछ अनोखी जानकारी (उंगलियों के निशान, आईरिस रंग, आवाज, आदि) की मदद से सबसे सरल मामले में - मेल और पासवर्ड की मदद से खुद को पास करने की कोशिश कर रहा है।
लॉग इन करें
यह पूर्व में किए गए प्रमाणीकरण के अनुसार कुछ कार्यों को करने के लिए प्राधिकरण का एक चेक और निर्धारण है
इस लेख के अंत में, हम इस मोबाइल एप्लिकेशन को बनाएंगे:

प्रमाणीकरण लगभग किसी भी अनुप्रयोग का एक अभिन्न अंग है। यह जानने के बाद कि उपयोगकर्ता कौन है, उपयोगकर्ता का विशिष्ट पहचानकर्ता, उपयोगकर्ता के पास क्या अनुमतियाँ हैं और क्या वे लॉग इन हैं, आपके एप्लिकेशन को सही विचार प्रदर्शित करने और उपयोगकर्ता में वर्तमान लॉग इन के लिए सही डेटा वापस करने की अनुमति देता है।
, , , , . , OAUTH ( ), MFA ( ) TOTP ( ).
. , . , , Auth0, Okta Amazon Cognito, .
, React Native Amazon Cognito AWS Amplify.
Amazon Cognito
AWS. Cognito , , , . Cognito , , Facebook, Google Amazon.
Cognito : .
User Pools
, . . , , , . — , , , , .
Identity pools
, , AWS. , -, API. . , Cognito Facebook Google.
, Amazon Cognito .
Amazon Cognito. , , AWS.

.
AWS .
, AWS AWS, Amazon S3 DynamoDB.
Cognito User Pools , , :
- MFA
- Amazon Cognito AWS Amplify
AWS Amplify Amazon Cognito . Amazon Cognito AWS Amplify. CLI, (, signUp, signIn signOut) JavaScript Amplify JavaScript.
Amplify , , React, React Native, Vue Angular.
?
, . .
Amazon Cognito Identity , (MAU). MAU — , : , , . .

CODING TIME
AWS Amplify: Telegram
I
o UI AWS Amplify, .
GitHub.



️
react-native init auth
iOS
cd auth && react-native run-ios
Android
cd auth && react-native run-android

AWS Amplify, .
.
App.js
import Icon from 'react-native-vector-icons/FontAwesome5'
const App = () => {
return (
<>
<Icon name="comments" size={30} color="#900" />
</>
)
}

AWS account
5 .
!!!
, 1$
Amplify Command Line Interface (CLI)

AWS Amplify React Native
React Native AWS Amplify
amplify init
:


, , , .
amplify add auth
. . auth ampify/backend/auth
, . default. Enter . Email( SMS ).

amplify push
All resources are updated in the cloud

AWS Amplify React Native ️
, :
yarn add aws-amplify @aws-amplify/core aws-amplify-react-native amazon-cognito-identity-js @react-native-community/netinfo
ios
cd ios && pod install && cd ..

/src App.js, index.js
/auth/index.js .
import { AppRegistry, YellowBox } from 'react-native'
import App from './src'
import { name as appName } from './app.json'
YellowBox.ignoreWarnings([
'Warning: AsyncStorage',
'Warning: componentWillReceiveProps',
'RCTRootView cancelTouches',
'not authenticated',
'Sending `onAnimatedValueUpdate`'
])
//window.LOG_LEVEL = 'DEBUG'
AppRegistry.registerComponent(appName, () => App)

Authenticator
Amplify.configure —
Authenticator — AWS Amplify Authentication API- , .
import React from 'react'
import {StatusBar} from 'react-native'
import Amplify from '@aws-amplify/core'
import {Authenticator} from 'aws-amplify-react-native'
import awsconfig from '../aws-exports'
Amplify.configure({
...awsconfig,
Analytics: {
disabled: true,
},
})
const App = () => {
return (
<>
<StatusBar barStyle="dark-content" />
<Authenticator usernameAttributes="email" />
</>
)
}
export default App
, UI :


signUpConfig
const signUpConfig = {
hideAllDefaults: true,
signUpFields: [
{
label: 'Email',
key: 'email',
required: true,
displayOrder: 1,
type: 'string',
},
{
label: 'Password',
key: 'password',
required: true,
displayOrder: 2,
type: 'password',
},
],
}
<Authenticator
usernameAttributes="email"
signUpConfig={signUpConfig}
/>

UI
/src/components/index.js
export * from './AmplifyTheme'
/src/components/AmplifyTheme/index.js
import { StyleSheet } from 'react-native'
export const deepSquidInk = '#152939'
export const linkUnderlayColor = '#FFF'
export const errorIconColor = '#30d0fe'
const AmplifyTheme = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'space-around',
paddingTop: 20,
width: '100%',
backgroundColor: '#FFF'
},
section: {
flex: 1,
width: '100%',
padding: 30
},
sectionHeader: {
width: '100%',
marginBottom: 32
},
sectionHeaderText: {
color: deepSquidInk,
fontSize: 20,
fontWeight: '500'
},
sectionFooter: {
width: '100%',
padding: 10,
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: 15,
marginBottom: 20
},
sectionFooterLink: {
fontSize: 14,
color: '#30d0fe',
alignItems: 'baseline',
textAlign: 'center'
},
navBar: {
marginTop: 35,
padding: 15,
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center'
},
navButton: {
marginLeft: 12,
borderRadius: 4
},
cell: {
flex: 1,
width: '50%'
},
errorRow: {
flexDirection: 'row',
justifyContent: 'center'
},
errorRowText: {
marginLeft: 10
},
photo: {
width: '100%'
},
album: {
width: '100%'
},
button: {
backgroundColor: '#30d0fe',
alignItems: 'center',
padding: 16
},
buttonDisabled: {
backgroundColor: '#85E4FF',
alignItems: 'center',
padding: 16
},
buttonText: {
color: '#fff',
fontSize: 14,
fontWeight: '600'
},
formField: {
marginBottom: 22
},
input: {
padding: 16,
borderWidth: 1,
borderRadius: 3,
borderColor: '#C4C4C4'
},
inputLabel: {
marginBottom: 8
},
phoneContainer: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center'
},
phoneInput: {
flex: 2,
padding: 16,
borderWidth: 1,
borderRadius: 3,
borderColor: '#C4C4C4'
},
picker: {
flex: 1,
height: 44
},
pickerItem: {
height: 44
}
})
export { AmplifyTheme }
Authenticator src/index.js
import {AmplifyTheme} from './components'
<Authenticator
usernameAttributes="email"
signUpConfig={signUpConfig}
theme={AmplifyTheme}
/>


/src/components/index.js
export * from './Localei18n'
C /src/components/Localei18n/index.js
import { NativeModules, Platform } from 'react-native'
import { I18n } from '@aws-amplify/core'
let langRegionLocale = 'en_US'
// If we have an Android phone
if (Platform.OS === 'android') {
langRegionLocale = NativeModules.I18nManager.localeIdentifier || ''
} else if (Platform.OS === 'ios') {
langRegionLocale = NativeModules.SettingsManager.settings.AppleLocale || ''
}
const authScreenLabels = {
en: {
'Sign Up': 'Create new account',
'Sign Up Account': 'Create a new account'
},
ru: {
'Sign Up': ' ',
'Forgot Password': ' ?',
'Sign In Account': ' ',
'Enter your email': ' email',
'Enter your password': ' ',
Password: '',
'Sign In': '',
'Please Sign In / Sign Up': ' / ',
'Sign in to your account': ' ',
'Create a new account': 'C ',
'Confirm a Code': ' ',
'Confirm Sign Up': ' ',
'Resend code': ' ',
'Back to Sign In': ' ',
Confirm: '',
'Confirmation Code': ' ',
'Sign Out': ''
}
}
// "en_US" -> "en", "es_CL" -> "es", etc
const languageLocale = langRegionLocale.substring(0, 2)
I18n.setLanguage(languageLocale)
I18n.putVocabularies(authScreenLabels)
const Localei18n = () => null
export { Localei18n }
Localei18n src/index.js
import {
AmplifyTheme,
Localei18n
} from './components'
<Localei18n />
<Authenticator
usernameAttributes="email"
signUpConfig={signUpConfig}
theme={AmplifyTheme}
/>
, , .

Done
II
- UI Amplify UX
- Amplify :
Data is stored unencrypted when using standard storage adapters (localStorage in the browser and AsyncStorage on React Native). Amplify gives you the option to use your own storage object to persist data. With this, you could write a thin wrapper around libraries like:
react-native-keychain
react-native-secure-storage
Expo’s secure store
, , , .
GitHub.


UI Kit
UI Kit, .
.

react-navigation
react-navigation 5, ( ):
yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view @react-navigation/stack
iOS
cd ios && pod install && cd ..
iOS Android, - .

react-native-keychain
react-native-keychain — react-native-keychain React Native.
yarn add react-native-keychain
iOS
cd ios && pod install && cd ..
, :
AWS Amplify Amazon Cognito . . , IdToken AccessToken, localStorage AsyncStorage React Native. Amplify , .
src/index.js
import React from 'react'
import Amplify from '@aws-amplify/core'
import * as Keychain from 'react-native-keychain'
import { ThemeProvider, DarkTheme, LightTheme } from 'react-native-unicorn-uikit'
import { useColorScheme } from 'react-native-appearance'
import AppNavigator from './AppNavigator'
import awsconfig from '../aws-exports'
const MEMORY_KEY_PREFIX = '@MyStorage:'
let dataMemory = {}
class MyStorage {
static syncPromise = null
static setItem(key, value) {
Keychain.setGenericPassword(MEMORY_KEY_PREFIX + key, value)
dataMemory[key] = value
return dataMemory[key]
}
static getItem(key) {
return Object.prototype.hasOwnProperty.call(dataMemory, key) ? dataMemory[key] : undefined
}
static removeItem(key) {
Keychain.resetGenericPassword()
return delete dataMemory[key]
}
static clear() {
dataMemory = {}
return dataMemory
}
}
Amplify.configure({
...awsconfig,
Analytics: {
disabled: false
},
storage: MyStorage
})
const App = () => {
const scheme = useColorScheme()
return (
<>
<ThemeProvider theme={scheme === 'dark' ? DarkTheme : LightTheme}>
<AppNavigator />
</ThemeProvider>
</>
)
}
export default App

, src/constants.js
import { Dimensions } from 'react-native'
export const BG = '#0B0B0B'
export const PINK = '#F20AF5'
export const PURPLE = '#7A1374'
export const BLUE = '#00FFFF'
export const GREEN = '#2E7767'
export const RED = '#FC2847'
export const LABEL_COLOR = BLUE
export const INPUT_COLOR = PINK
export const ERROR_COLOR = RED
export const HELP_COLOR = '#999999'
export const BORDER_COLOR = BLUE
export const DISABLED_COLOR = '#777777'
export const DISABLED_BACKGROUND_COLOR = '#eeeeee'
export const win = Dimensions.get('window')
export const W = win.width
export const H = win.height
export const Device = {
// eslint-disable-next-line
select(variants) {
if (W >= 300 && W <= 314) return variants.mobile300 || {}
if (W >= 315 && W <= 341) return variants.iphone5 || {}
if (W >= 342 && W <= 359) return variants.mobile342 || {}
if (W >= 360 && W <= 374) return variants.mi5 || {}
if (W >= 375 && W <= 399) return variants.iphone678 || {}
if (W >= 400 && W <= 409) return variants.mobile400 || {}
if (W >= 410 && W <= 414) return variants.googlePixel || {}
if (W >= 415 && W <= 434) return variants.mobile415 || {}
if (W >= 435 && W <= 480) return variants.redmiNote5 || {}
}
}
export const goBack = navigation => () => navigation.goBack()
export const onScreen = (screen, navigation, obj) => () => {
navigation.navigate(screen, obj)
}
export const goHome = navigation => () => navigation.popToTop()()

AppNavigator
src/AppNavigator.js
import * as React from 'react'
import { createStackNavigator } from '@react-navigation/stack'
import { Hello } from './screens/Authenticator'
const Stack = createStackNavigator()
const AppNavigator = () => {
return (
<Stack.Navigator
screenOptions={{
headerShown: false
}}
initialRouteName="HELLO"
>
<Stack.Screen name="HELLO" component={Hello} />
</Stack.Navigator>
)
}
export default AppNavigator

Hello screen
src/screens/Authenticator/index.js

export * from './Hello'
src/screens/Authenticator/Hello/index.js
useEffect , true User, false .
import React, { useEffect, useState } from 'react'
import { Auth } from 'aws-amplify'
import * as Keychain from 'react-native-keychain'
import { AppContainer, Button, Space, H6 } from 'react-native-unicorn-uikit'
import { onScreen } from '../../../constants'
const Hello = ({ navigation }) => {
const [loading, setLoading] = useState(false)
useEffect(() => {
setLoading(true)
const key = async () => {
try {
const credentials = await Keychain.getInternetCredentials('auth')
if (credentials) {
const { username, password } = credentials
const user = await Auth.signIn(username, password)
setLoading(false)
user && onScreen('USER', navigation)()
} else {
setLoading(false)
}
} catch (err) {
console.log('error', err) // eslint-disable-line
setLoading(false)
}
}
key()
}, []) // eslint-disable-line
return (
<AppContainer loading={loading}>
<Space height={200} />
<Button title="Sign In" onPress={onScreen('SIGN_IN', navigation)} />
<Space height={10} />
<H6 title="or" textStyle={{ alignSelf: 'center' }} />
<Space height={15} />
<Button title="Sign Up" onPress={onScreen('SIGN_UP', navigation)} />
</AppContainer>
)
}
export { Hello }
.
SignUp screen
SIGN_UP src/screens/Authenticator/SignUp/index.js, Auth.signUp

import React, { useState } from 'react'
import { Auth } from 'aws-amplify'
import * as Keychain from 'react-native-keychain'
import { Formik } from 'formik'
import * as Yup from 'yup'
import { AppContainer, Space, Button, Input, TextError } from 'react-native-unicorn-uikit'
import { onScreen, goBack } from '../../../constants'
const SignUp = ({ navigation }) => {
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const _onPress = async (values) => {
const { email, password, passwordConfirmation } = values
if (password !== passwordConfirmation) {
setError('Passwords do not match!')
} else {
setLoading(true)
setError('')
try {
const user = await Auth.signUp(email, password)
await Keychain.setInternetCredentials('auth', email, password)
user && onScreen('CONFIRM_SIGN_UP', navigation, { email, password })()
setLoading(false)
} catch (err) {
setLoading(false)
if (err.code === 'UserNotConfirmedException') {
setError('Account not verified yet')
} else if (err.code === 'PasswordResetRequiredException') {
setError('Existing user found. Please reset your password')
} else if (err.code === 'NotAuthorizedException') {
setError('Forgot Password?')
} else if (err.code === 'UserNotFoundException') {
setError('User does not exist!')
} else {
setError(err.code)
}
}
}
}
return (
<>
<AppContainer onPress={goBack(navigation)} title="Sign Up" loading={loading}>
<Space height={80} />
<Formik
initialValues={{ email: '', password: '', passwordConfirmation: '' }}
onSubmit={(values) => _onPress(values)}
validationSchema={Yup.object().shape({
email: Yup.string().email().required(),
password: Yup.string().min(6).required(),
passwordConfirmation: Yup.string().min(6).required()
})}
>
{({ values, handleChange, errors, setFieldTouched, touched, isValid, handleSubmit }) => (
<>
<Input
name="email"
value={values.email}
onChangeText={handleChange('email')}
onBlur={() => setFieldTouched('email')}
placeholder="E-mail"
touched={touched}
errors={errors}
autoCapitalize="none"
/>
<Input
name="password"
value={values.password}
onChangeText={handleChange('password')}
onBlur={() => setFieldTouched('password')}
placeholder="Password"
touched={touched}
errors={errors}
secureTextEntry
/>
<Input
name="passwordConfirmation"
value={values.passwordConfirmation}
onChangeText={handleChange('passwordConfirmation')}
onBlur={() => setFieldTouched('passwordConfirmation')}
placeholder="Password confirm"
touched={touched}
errors={errors}
secureTextEntry
/>
<Space height={30} />
{error !== '' && <TextError title={error} textStyle={{ alignSelf: 'center' }} />}
<Button title="Sign Up" disabled={!isValid} onPress={handleSubmit} formik />
</>
)}
</Formik>
</AppContainer>
</>
)
}
export { SignUp }

ConfirmSignUp screen
, , . CONFIRM_SIGN_UP src/screens/Authenticator/ConfirmSignUp/index.js

import React, { useState } from 'react'
import { Auth } from 'aws-amplify'
import { Formik } from 'formik'
import * as Yup from 'yup'
import { AppContainer, Button, Space, ButtonLink, TextError, Input } from 'react-native-unicorn-uikit'
import { onScreen, goBack } from '../../../constants'
const ConfirmSignUp = ({ route, navigation }) => {
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const _onPress = async (values) => {
setLoading(true)
setError('')
try {
const { code } = values
const { email, password } = route.params
await Auth.confirmSignUp(email, code, { forceAliasCreation: true })
const user = await Auth.signIn(email, password)
user && onScreen('USER', navigation)()
setLoading(false)
} catch (err) {
setLoading(false)
setError(err.message)
if (err.code === 'UserNotConfirmedException') {
setError('Account not verified yet')
} else if (err.code === 'PasswordResetRequiredException') {
setError('Existing user found. Please reset your password')
} else if (err.code === 'NotAuthorizedException') {
setError('Forgot Password?')
} else if (err.code === 'UserNotFoundException') {
setError('User does not exist!')
}
}
}
const _onResend = async () => {
try {
const { email } = route.params
await Auth.resendSignUp(email)
} catch (err) {
setError(err.message)
}
}
return (
<>
<AppContainer title="Confirmation" onPress={goBack(navigation)} loading={loading}>
<Formik
initialValues={{ code: '' }}
onSubmit={(values) => _onPress(values)}
validationSchema={Yup.object().shape({
code: Yup.string().min(6).required()
})}
>
{({ values, handleChange, errors, setFieldTouched, touched, isValid, handleSubmit }) => (
<>
<Space height={180} />
<Input
name="code"
value={values.code}
onChangeText={handleChange('code')}
onBlur={() => setFieldTouched('code')}
placeholder="Insert code"
touched={touched}
errors={errors}
/>
<ButtonLink title="Resend code?" onPress={_onResend} textStyle={{ alignSelf: 'center' }} />
{error !== 'Forgot Password?' && <TextError title={error} />}
<Button title="Confirm" disabled={!isValid} onPress={handleSubmit} formik />
<Space height={50} />
</>
)}
</Formik>
</AppContainer>
</>
)
}
export { ConfirmSignUp }
ResendSignUp
, . Resend code? Auth.resendSignUp(userInfo.email)
Auth.confirmSignUp(email, code, { forceAliasCreation: true })
Auth.signIn(email, password)

User screen
USER, c src/screens/Authenticator/User/index.js

import React, { useState, useEffect } from 'react'
import { Auth } from 'aws-amplify'
import * as Keychain from 'react-native-keychain'
import { AppContainer, Button } from 'react-native-unicorn-uikit'
import { goHome } from '../../../constants'
const User = ({ navigation }) => {
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
useEffect(() => {
const checkUser = async () => {
await Auth.currentAuthenticatedUser()
}
checkUser()
})
const _onPress = async () => {
setLoading(true)
try {
await Auth.signOut()
await Keychain.resetInternetCredentials('auth')
goHome(navigation)()
} catch (err) {
setError(err.message)
}
}
return (
<AppContainer message={error} loading={loading}>
<Button title="Sign Out" onPress={_onPress} />
</AppContainer>
)
}
export { User }

SignIn screen
, , . SIGN_IN src/screens/Authenticator/SignIn/index.js

import React, { useState } from 'react'
import { Auth } from 'aws-amplify'
import * as Keychain from 'react-native-keychain'
import { Formik } from 'formik'
import * as Yup from 'yup'
import { AppContainer, Button, Space, ButtonLink, TextError, Input } from 'react-native-unicorn-uikit'
import { onScreen, goBack } from '../../../constants'
const SignIn = ({ navigation }) => {
const [userInfo, setUserInfo] = useState('')
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const _onPress = async (values) => {
setLoading(true)
setError('')
try {
const { email, password } = values
const user = await Auth.signIn(email, password)
await Keychain.setInternetCredentials('auth', email, password)
user && onScreen('USER', navigation)()
setLoading(false)
} catch (err) {
setLoading(false)
if (err.code === 'UserNotConfirmedException') {
setError('Account not verified yet')
} else if (err.code === 'PasswordResetRequiredException') {
setError('Existing user found. Please reset your password')
} else if (err.code === 'NotAuthorizedException') {
setError('Forgot Password?')
} else if (err.code === 'UserNotFoundException') {
setError('User does not exist!')
} else {
setError(err.code)
}
}
}
return (
<>
<AppContainer onPress={goBack(navigation)} title="Sign In" loading={loading}>
<Space height={140} />
<Formik
initialValues={{ email: '', password: '' }}
onSubmit={(values) => _onPress(values) && setUserInfo(values.email)}
validationSchema={Yup.object().shape({
email: Yup.string().email().required(),
password: Yup.string().min(6).required()
})}
>
{({ values, handleChange, errors, setFieldTouched, touched, isValid, handleSubmit }) => (
<>
<Input
name="email"
value={values.email}
onChangeText={handleChange('email')}
onBlur={() => setFieldTouched('email')}
placeholder="E-mail"
touched={touched}
errors={errors}
autoCapitalize="none"
/>
<Input
name="password"
value={values.password}
onChangeText={handleChange('password')}
onBlur={() => setFieldTouched('password')}
placeholder="Password"
touched={touched}
errors={errors}
secureTextEntry
/>
{error !== 'Forgot Password?' && <TextError title={error} textStyle={{ alignSelf: 'center' }} />}
{error === 'Forgot Password?' && (
<ButtonLink
title={error}
onPress={onScreen('FORGOT', navigation, userInfo)}
textStyle={{ alignSelf: 'center' }}
/>
)}
<Space height={30} />
<Button title="Sign In" disabled={!isValid} onPress={handleSubmit} formik />
</>
)}
</Formik>
</AppContainer>
</>
)
}
export { SignIn }

Forgot password screen
, USER, , , Forgot Password? .

FORGOT src/screens/Authenticator/Forgot/index.js

import React, { useState } from 'react'
import { Auth } from 'aws-amplify'
import { Formik } from 'formik'
import * as Yup from 'yup'
import { AppContainer, Button, Input } from 'react-native-unicorn-uikit'
import { onScreen, goBack } from '../../../constants'
const Forgot = ({ route, navigation }) => {
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const _onPress = async (values) => {
setLoading(true)
try {
const { email } = values
const user = await Auth.forgotPassword(email)
user && onScreen('FORGOT_PASSWORD_SUBMIT', navigation, email)()
setLoading(false)
} catch (err) {
setError(error)
}
}
return (
<>
<AppContainer title="Forgot" onPress={goBack(navigation)} loading={loading}>
<Formik
initialValues={{ email: route.params }}
onSubmit={(values) => _onPress(values)}
validationSchema={Yup.object().shape({
email: Yup.string().email().required()
})}
>
{({ values, handleChange, errors, setFieldTouched, touched, isValid, handleSubmit }) => (
<>
<Input
name="email"
value={values.email}
onChangeText={handleChange('email')}
onBlur={() => setFieldTouched('email')}
placeholder="E-mail"
touched={touched}
errors={errors}
autoCapitalize="none"
/>
<Button title="Confirm" disabled={!isValid} onPress={handleSubmit} formik />
</>
)}
</Formik>
</AppContainer>
</>
)
}
export { Forgot }

Forgot Password Submit
e-mail, Auth.forgotPassword(email) , , FORGOT_PASSWORD_SUBMIT src/screens/Authenticator/ForgotPassSubmit/index.js

import React, { useState } from 'react'
import { Platform } from 'react-native'
import { Auth } from 'aws-amplify'
import * as Keychain from 'react-native-keychain'
import { Formik } from 'formik'
import * as Yup from 'yup'
import { AppContainer, Button, Space, Input, TextError } from 'react-native-unicorn-uikit'
import { onScreen, goBack } from '../../../constants'
const ForgotPassSubmit = ({ route, navigation }) => {
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const _onPress = async (values) => {
setLoading(true)
try {
const { email, code, password } = values
await Auth.forgotPasswordSubmit(email, code, password)
await Keychain.setInternetCredentials('auth', email, password)
onScreen('USER', navigation)()
setLoading(false)
} catch (err) {
setLoading(false)
setError(err.message)
}
}
return (
<>
<AppContainer title="Confirmation" onPress={goBack(navigation)} loading={loading}>
<Space height={Platform.OS === 'ios' ? 20 : 150} />
<Formik
initialValues={{ email: route.params, code: '', password: '', passwordConfirmation: '' }}
onSubmit={(values) => _onPress(values)}
validationSchema={Yup.object().shape({
email: Yup.string().email().required(),
code: Yup.string().min(6).required(),
password: Yup.string().min(6).required(),
passwordConfirmation: Yup.string().min(6).required()
})}
>
{({ values, handleChange, errors, setFieldTouched, touched, isValid, handleSubmit }) => (
<>
<Input
name="email"
value={values.email}
onChangeText={handleChange('email')}
onBlur={() => setFieldTouched('email')}
placeholder="E-mail"
touched={touched}
errors={errors}
autoCapitalize="none"
/>
<Input
name="code"
value={values.code}
onChangeText={handleChange('code')}
onBlur={() => setFieldTouched('code')}
placeholder="Code"
touched={touched}
errors={errors}
/>
<Input
name="password"
value={values.password}
onChangeText={handleChange('password')}
onBlur={() => setFieldTouched('password')}
placeholder="Password"
touched={touched}
errors={errors}
secureTextEntry
/>
<Input
name="passwordConfirmation"
value={values.passwordConfirmation}
onChangeText={handleChange('passwordConfirmation')}
onBlur={() => setFieldTouched('passwordConfirmation')}
placeholder="Password confirm"
touched={touched}
errors={errors}
secureTextEntry
/>
{error !== '' && <TextError title={error} textStyle={{ alignSelf: 'center' }} />}
<Space height={30} />
<Button title="Confirm" disabled={!isValid} onPress={handleSubmit} formik />
</>
)}
</Formik>
</AppContainer>
</>
)
}
export { ForgotPassSubmit }
, , ,
Auth.forgotPasswordSubmit(email, code, password)
USER.

src/screens/Authenticator/index.js
export * from './Hello'
export * from './User'
export * from './SignIn'
export * from './SignUp'
export * from './Forgot'
export * from './ForgotPassSubmit'
export * from './ConfirmSignUp'

Udpate AppNavigator
:
import * as React from 'react'
import { createStackNavigator } from '@react-navigation/stack'
import { Hello, SignUp, SignIn, ConfirmSignUp, User, Forgot, ForgotPassSubmit } from './screens/Authenticator'
const Stack = createStackNavigator()
const AppNavigator = () => {
return (
<Stack.Navigator
screenOptions={{
headerShown: false
}}
initialRouteName="HELLO"
>
<Stack.Screen name="HELLO" component={Hello} />
<Stack.Screen name="SIGN_UP" component={SignUp} />
<Stack.Screen name="SIGN_IN" component={SignIn} />
<Stack.Screen name="FORGOT" component={Forgot} />
<Stack.Screen name="FORGOT_PASSWORD_SUBMIT" component={ForgotPassSubmit} />
<Stack.Screen name="CONFIRM_SIGN_UP" component={ConfirmSignUp} />
<Stack.Screen name="USER" component={User} />
</Stack.Navigator>
)
}
export default AppNavigator

Clean Up
चूंकि हम एक कस्टम थीम का उपयोग करते हैं, हम घटकों को हटाते हैं AmplifyTheme और Localei18n

डिबग
यह समझने के लिए कि आपके आवेदन में टोकन के साथ क्या होता है, रूट /index.js में जोड़ें
window.LOG_LEVEL = 'DEBUG'
हम एप्लिकेशन लॉन्च करते हैं और कस्टम प्रमाणीकरण प्राप्त करते हैं।
किया हुआ
विषय को जारी रखने के लिए, लेख देखें DataStore - CRUD (पढ़ें अपडेट हटाएं बनाएं)
