์ธ์ฆ ๊ธฐ๋ฅ์ ์ํด AWS Cognito๋ฅผ Amplify ์์์ ์ฌ์ฉํ ๊ฒ์ด๋ค.
๊ธฐ์กด AWS Cognito ๋ฆฌ์์ค์ ํตํฉํ ์๋ ์๊ณ , Amplify Studio์์ ์๋ก ๋ฆฌ์์ค๋ฅผ ์์ฑํ ์๋ ์๋ค.
Cognito๋ ์ฌ์ฉ์ ์ธ์ฆ ๋ฐ ๊ถํ ๋ถ์ฌ๋ฅผ ์ฒ๋ฆฌํ๋ ์๋น์ค์ด๋ค. Cognito์์ ์ฌ์ฉ์ ํ์ ์์ฑํ๋ฉด ๊ฐ์ ๋ฐ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ์ฝ๊ฒ ์ฑ์ ์ถ๊ฐํ ์ ์๋ค.
1. AWS - ์ธ์ฆ ๊ตฌ์ฑ ๋ฐ ๋ฐฐํฌ
Amplify ์คํ๋์ค์์ ์ธ์ฆ ๊ธฐ๋ฅ์ ์ค์ ํ๋ฉด CloudFormation์์ Cognito๋ฅผ ์ฝ๋ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑํ๋ค.
๋ก๊ทธ์ธ ๋ฐฉ์๊ณผ ํ์๊ฐ์ ๋ฐฉ์์ ์ ํํ ํ, Deployment๋ฅผ ์งํํ๋ค.
๋ก๊ทธ์ธ ๋ฐฉ์์ ์ด๋ฏธ์ง์ฒ๋ผ ์ ํ๋ฒํธ, ์ด๋ฉ์ผ, ์ ์ ๋ช , ๊ฐํธ๋ก๊ทธ์ธ(ํ์ด์ค๋ถ, ๊ตฌ๊ธ, ์๋ง์กด, ์ ํ) ์ค ์ ํํ ์ ์๊ณ , ํ์๊ฐ์ ๋ฐฉ์์์๋ ์ฌ์ฉ์๋ก๋ถํฐ ๋ฐ์ ์ ๋ณด, ๋น๋ฐ๋ฒํธ ๊ฐ๋, ๊ฐ์ ์ธ์ฆ ๋ฐฉ์ ๋ฑ์ ์ค์ ํ ์ ์๋ค.
2. Local - Amplify pull
๋ก์ปฌ์์ pull ๋ช ๋ น์ด๋ฅผ ์ํํด AWS ์ฝ์์์ ์ค์ ํ ๋ด์ฉ์ ๊ฐ์ ธ์ค๋๋ก ํ๋ค.
amplify pull --appId (AppId) --envname (Status)
backend/auth/(์ฑ์ด๋ฆ)/build/parameters.json์ ์์ ๊ตฌ์ฑํ๋ ์ ๋ณด๊ฐ ๊ทธ๋๋ก ๋ค์ด๊ฐ๊ณ , aws-exports.js ํ์ผ์์๋ ์ธ์ฆ ๊ด๋ จ ์ ๋ณด๊ฐ ์ ๋ฐ์ดํธ๋๋ค.
3. Local - UI ๊ตฌ์ฑ
ํ๋ฉด ๊ตฌ์ฑ์ ํ์ํ ํจํค์ง๋ค์ ์ค์นํ๋ค.
yarn add @aws-amplify/ui-react-native aws-amplify @aws-amplify/react-native react-native-safe-area-context @react-native-community/netinfo @react-native-async-storage/async-storage react-native-get-random-values
# ๋๋
npm install @aws-amplify/ui-react-native aws-amplify @aws-amplify/react-native react-native-safe-area-context @react-native-community/netinfo @react-native-async-storage/async-storage react-native-get-random-values
๋ค์ ์ฝ๋๋ฅผ ์ฌ์ฉํด ๋ก๊ทธ์ธ, ํ์๊ฐ์ , ๋ก๊ทธ์์ ๋ฑ์ ๊ธฐ๋ฅ์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ค. ๊ณต์ ๋ฌธ์๋ฅผ ๋ณด๋ฉด ๋ ๋ค์ํ ๊ธฐ๋ฅ์ด ๋์์๋ค.
import { signIn } from 'aws-amplify/auth';
import { signUp } from 'aws-amplify/auth';
import { confirmSignUp } from 'aws-amplify/auth';
import { signOut } from 'aws-amplify/auth';
Enable sign-up, sign-in, and sign-out - React Native - AWS Amplify Gen 1 Documentation
Learn how to use Amplify's sign-up, sign-in, and sign-out APIs. AWS Amplify Documentation
docs.amplify.aws
๋ก๊ทธ์ธ ํ๋ฉด, ํ์๊ฐ์ ํ๋ฉด, ์ธ์ฆ ์ฝ๋ ์ ๋ ฅ ํ๋ฉด, ๋ก๊ทธ์ธ ์ฑ๊ณต ํ๋ฉด์ ๊ตฌํํ๋ค.
SignIn.js
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { signIn } from 'aws-amplify/auth';
import AppTextInput from '../components/AppTextInput';
import AppButton from '../components/AppButton';
function SignIn({ navigation, updateAuthState }) {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
async function handleSignIn() {
try {
await signIn({ username, password });
console.log('โ
Success');
updateAuthState('loggedIn');
} catch (error) {
console.log('โ Error signing in...', error);
}
}
return (
<SafeAreaView style={styles.safeAreaContainer}>
<View style={styles.container}>
<Text style={styles.title}>Sign in to your account</Text>
<AppTextInput
value={username}
onChangeText={text => setUsername(text)}
leftIcon="account"
placeholder="Enter username"
autoCapitalize="none"
keyboardType="email-address"
textContentType="emailAddress"
/>
<AppTextInput
value={password}
onChangeText={text => setPassword(text)}
leftIcon="lock"
placeholder="Enter password"
autoCapitalize="none"
autoCorrect={false}
secureTextEntry
textContentType="password"
/>
<AppButton title="Login" onPress={handleSignIn} />
<View style={styles.footerButtonContainer}>
<TouchableOpacity onPress={() => navigation.navigate('SignUp')}>
<Text style={styles.forgotPasswordButtonText}>
Dont have an account? Sign Up
</Text>
</TouchableOpacity>
</View>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
safeAreaContainer: {
flex: 1,
backgroundColor: 'white'
},
container: {
flex: 1,
alignItems: 'center'
},
title: {
fontSize: 20,
color: '#202020',
fontWeight: '500',
marginVertical: 15
},
footerButtonContainer: {
marginVertical: 15,
justifyContent: 'center',
alignItems: 'center'
},
forgotPasswordButtonText: {
color: 'tomato',
fontSize: 18,
fontWeight: '600'
}
});
export default SignIn;
SignUp.js
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { signUp } from 'aws-amplify/auth';
import AppTextInput from '../components/AppTextInput';
import AppButton from '../components/AppButton';
function SignUp({ navigation }) {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [email, setEmail] = useState('');
async function handleSignUp() {
try {
const { isSignUpComplete, userId, nextStep } = await signUp({ username, password, options: { userAttributes: { email } } });
console.log('โ
Sign-up Confirmed : ', userId);
navigation.navigate('ConfirmSignUp');
} catch (error) {
console.log('โ Error signing up...', error);
}
}
return (
<SafeAreaView style={styles.safeAreaContainer}>
<View style={styles.container}>
<Text style={styles.title}>Create a new account</Text>
<AppTextInput
value={username}
onChangeText={text => setUsername(text)}
leftIcon="account"
placeholder="Enter username"
autoCapitalize="none"
keyboardType="email-address"
textContentType="emailAddress"
/>
<AppTextInput
value={password}
onChangeText={text => setPassword(text)}
leftIcon="lock"
placeholder="Enter password"
autoCapitalize="none"
autoCorrect={false}
secureTextEntry
textContentType="password"
/>
<AppTextInput
value={email}
onChangeText={text => setEmail(text)}
leftIcon="email"
placeholder="Enter email"
autoCapitalize="none"
keyboardType="email-address"
textContentType="emailAddress"
/>
<AppButton title="Sign Up" onPress={handleSignUp} />
<View style={styles.footerButtonContainer}>
<TouchableOpacity onPress={() => navigation.navigate('SignIn')}>
<Text style={styles.forgotPasswordButtonText}>
Already have an account? Sign In
</Text>
</TouchableOpacity>
</View>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
safeAreaContainer: {
flex: 1,
backgroundColor: 'white'
},
container: {
flex: 1,
alignItems: 'center'
},
title: {
fontSize: 20,
color: '#202020',
fontWeight: '500',
marginVertical: 15
},
footerButtonContainer: {
marginVertical: 15,
justifyContent: 'center',
alignItems: 'center'
},
forgotPasswordButtonText: {
color: 'tomato',
fontSize: 18,
fontWeight: '600'
}
});
export default SignUp;
ConfirmSignUp.js
import React, { useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { confirmSignUp } from 'aws-amplify/auth';
import AppTextInput from '../components/AppTextInput';
import AppButton from '../components/AppButton';
function ConfirmSignUp({ navigation }) {
const [username, setUsername] = useState('');
const [confirmationCode, setConfirmationCode] = useState('');
async function handleSignUpConfirmation() {
try {
await confirmSignUp({username, confirmationCode});
console.log('โ
Code confirmed');
navigation.navigate('SignIn');
} catch (error) {
console.log(
'โ Error confirming...', error
);
}
}
return (
<SafeAreaView style={styles.safeAreaContainer}>
<View style={styles.container}>
<Text style={styles.title}>Confirm Sign Up</Text>
<AppTextInput
value={username}
onChangeText={text => setUsername(text)}
leftIcon="account"
placeholder="Enter username"
autoCapitalize="none"
keyboardType="email-address"
textContentType="emailAddress"
/>
<AppTextInput
value={confirmationCode}
onChangeText={text => setConfirmationCode(text)}
leftIcon="numeric"
placeholder="Enter verification code"
keyboardType="numeric"
/>
<AppButton title="Confirm Sign Up" onPress={handleSignUpConfirmation} />
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
safeAreaContainer: {
flex: 1,
backgroundColor: 'white'
},
container: {
flex: 1,
alignItems: 'center'
},
title: {
fontSize: 20,
color: '#202020',
fontWeight: '500',
marginVertical: 15
}
});
export default ConfirmSignUp;
Home.js
import React from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import { signOut } from 'aws-amplify/auth';
function Home({ updateAuthState }) {
async function handleSignOut() {
try {
await signOut();
updateAuthState('loggedOut');
} catch (error) {
console.log('Error signing out: ', error);
}
}
return (
<View style={styles.container}>
<Text>๐ + ๐</Text>
<Button title="Sign Out" color="tomato" onPress={handleSignOut} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
marginTop: 20
}
});
export default Home;
์ฑ์ ์คํํ๋ฉด ์ธ์ฆ flow๊ฐ ์ ์๋ํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
ํ์๊ฐ์ ํ๋ฉด์์ Amplify Studio์์ ์ ํํ๋ ์ ๋ณด๋ค์ ์ ๋ ฅํ๋๋ก ๊ตฌ์ฑํ๊ณ , confirm ํ๋ฉด์ผ๋ก ๋์ด๊ฐ๋ฉด ์ ๋ ฅํ ๋ฉ์ผ๋ก ์ธ์ฆ์ฝ๋๊ฐ ๋ฐ์ก๋๋ค. ์ธ์ฆ์ฝ๋๋ฅผ ๋ฐ๋ฅด๊ฒ ์ ๋ ฅํ๋ฉด ํ์๊ฐ์ ์ด ์๋ฃ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ์ ํ ์ ๋ณด๋ค๋ก ๋ก๊ทธ์ธํ๋ฉด ๋ก๊ทธ์ธ ์ฑ๊ณต ํ๋ฉด์ด ๋์ค๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
ํ์๊ฐ์ ์ด ์ ์์ ์ผ๋ก ์๋ฃ๋๋ฉด Amplify Studio์ Cognito ์ ์ ํ์์๋ ์ฌ์ฉ์๊ฐ ์ถ๊ฐ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
'AWS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
AWS Amplify๋ฅผ ์ด์ฉํ React Native ์ฑ ๊ฐ๋ฐ๊ธฐ (1) ํ๊ฒฝ์ค์ (0) | 2024.05.05 |
---|---|
AWS Amplify๋ (0) | 2024.04.14 |
[AWS] CLF-C02: Cloud Practitioner Essentials ๊ฐ์ ๋ ธํธ (3) (0) | 2024.03.31 |
[AWS] CLF-C02: Cloud Practitioner Essentials ๊ฐ์ ๋ ธํธ (2) (0) | 2024.03.24 |
[AWS] CLF-C02: Cloud Practitioner Essentials ๊ฐ์ ๋ ธํธ (1) (1) | 2024.03.10 |