AWS Amplify를 사용한 바이브레이션 인증

이 문서에서 Amplify를 사용하여 AWS Cognito 기능을 사용하는 로그인 및 등록 프로세스를 응용 프로그램에 추가하는 방법을 설명할 것입니다.
알다시피 Flitter는 안드로이드와 iOS를 위한 크로스플랫폼 모바일 개발 프레임워크입니다.Amplify는 확장 가능한 전체 스택 어플리케이션을 구축하는 AWS 서비스 그룹입니다.한편, 구글에 Firebase가 있듯이 AWS에도 Amplify가 있다.
간단한 로그인과 등록 프로그램을 만들 것입니다.
▶ 보기
👶 초기 항목Github
😎 완료된 프로젝트Github
응용 프로그램을 만들려면 다음 도구가 필요합니다.🔧
  • Flutter버전 1.20.0
  • 의 최신 버전Amplify CLI.다음 명령을 사용하여 최신 Amplify CLI를 설치할 수 있습니다.
  • $ npm install -g @aws-amplify/[email protected]
    

    우리 뭐하지?



    1. 바이브레이션 프로젝트 만들기


    다음 명령을 사용하여 간단하게 떨림 항목을 만들 수 있습니다.이 예에서, 나는 프로젝트 이름 amplify_login_app 을 사용할 것이다.
    $ flutter create todo_amplify
    
    그리고amplify를 현재 프로젝트 go 프로젝트 디렉터리에 추가하고 새 터미널을 엽니다.다음 명령을 실행합니다.
    $ amplify init
    

    기본 옵션을 선택하고 계속합니다.
    Amplify를 초기화하면 프로젝트 구조가 다음과 같습니다.

    보시다시피 자동으로 생성된 파일이 있습니다. calledamplifyconfiguration.dart이 파일은 초기화 과정에서 생성된 것입니다.이 파일의 이름을 바꾸거나 수정하지 마십시오. 이 파일이 잠시 후에 필요합니다.

    인증 추가


    우리 프로그램에 인증을 추가하는 것은 아주 좋은 선택입니다.어떻게 하는지 보여줘.우선 현재 작업 디렉터리에서 다음 명령을 실행합니다.
    $ amplify add auth
    
    이 설정은 나중에 편집할 수 없습니다.

    우리의 예에서, 우리는 로그인 방법을 전자 우편으로 선택했다.요구 사항에 따라 사용자 이름, 전화 번호 또는 이메일 기반 인증을 선택할 수 있습니다.
    그리고 우리는 amplify push를 실행하여 클라우드에 변경 사항을 배치하고 업데이트amplifyconfiguration.dart해야 한다.
    이제 인코딩 작업을 좀 합시다.AWS Cognito 종속성을 프로젝트에 추가해야 합니다.우리는 의존항amplify_coreamplify_auth_cognitopubspec.yaml에 추가함으로써 이 점을 실현할 수 있다.
  • amplify_core는 전진 증폭의 핵심 모듈이다.만약 어떤 확대 라이브러리를 사용한다면, 이 의존항을 항상 추가해야 합니다.
  • amplify_auth_cognito 확대 검증 기능을 응용 프로그램에 추가하는 데 사용합니다.
  • 그리고 flutter pub get로 모든 의존항을 다운로드할 수 있다.
    만약android 개발자라면 minSdkVersion 버전을 21로 업데이트해야 합니다.amplify_core 최소 API 레벨이 21이어야 하기 때문입니다.이렇게 하려면 애플리케이션 레벨build.gradle 파일로 이동합니다.

    Amplify 를 애플리케이션에 통합해 보겠습니다.
    main.dart 파일에서 보듯이 MyApp은 저희 응용 프로그램의 루트 위젯입니다.나는 모든 작은 위젯을 삭제하고 다음과 같이 변경할 것이다.
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(
        MaterialApp(
          title: 'Amplify TODO',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: AmplifyTODO(),
        ),
      );
    }
    
    class AmplifyTODO extends StatefulWidget {
      AmplifyTODO({Key key}) : super(key: key);
    
      @override
      _AmplifyTODOState createState() => _AmplifyTODOState();
    }
    
    class _AmplifyTODOState extends State<AmplifyTODO> {
      @override
      Widget build(BuildContext context) {
        return Scaffold();
      }
    }
    
    amplify를 초기화하려면 initState 방법에서 다음과 같은 방법을 실행해야 합니다.
    import 'package:amplify_core/amplify_core.dart';
    import 'package:amplify_todo/amplifyconfiguration.dart';
    import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
    
    
    class _AmplifyTODOState extends State<AmplifyTODO> {
      bool _amplifyConfigured = false;
      Amplify _amplifyInstance = Amplify();
    
      Future<void> _configureAmplify() async {
        try {
          AmplifyAuthCognito auth = AmplifyAuthCognito();
          _amplifyInstance.addPlugin(
            authPlugins: [auth],
          );
          await _amplifyInstance.configure(amplifyconfig);
    
          setState(() => _amplifyConfigured = true);
        } catch (e) {
          print(e);
          setState(() => _amplifyConfigured = false);
        }
      }
    
      @override
      void initState() {
        super.initState();
        _configureAmplify();
      }
    ...
    
    우선, 우리는 AmplifyAuthCognito의 실례를 만들고, amplify의 실례를 추가합니다.amplify init 동안 자동으로 생성된 파일을 기억하십니까?마지막 단계에서 우리는 amplifyconfig의 값을 _amplifyInstance에 추가할 것이다.만약 이 과정이 성공적으로 완성된다면, 우리는 _amplifyConfiguredtrue로 설정할 것입니다.오류가 발생하면 false로 설정합니다.
    이제 모든 것이 정상인지 프로그램을 실행해 봅시다.
    ⚠ 참고 핫 재부팅을 수행하면 다음 예외가 발생할 수 있습니다.
    PlatformException(AmplifyException, User-Agent was already configured successfully., {cause: null, recoverySuggestion: User-Agent is configured internally during Amplify configuration. This method should not be called externally.}, null)
    
    Amplify를 구성했는데 라이브러리에서 핫 재부팅이 감지되지 않았기 때문입니다.미래의 버전에서, 그들은 이 오류를 복구할 것이다.
    로그인과 등록 화면을 만들 때가 되었다.화면 폴더에 화면을 만들 것입니다. 아래와 같습니다.
  • 파일email_validator.dart에는 문자열이 전자 우편인지 확인하는 함수가 포함되어 있습니다.
  • 먼저 실현합시다signup_screen.dart. 아래와 같습니다.
    import 'package:todo_amplify/screens/email_confirmation_screen.dart';
    import 'package:todo_amplify/util/email_validator.dart';
    import 'package:flutter/material.dart';
    
    class SignUpScreen extends StatelessWidget {
      SignUpScreen({Key key}) : super(key: key);
    
      final TextEditingController _emailController = TextEditingController();
      final TextEditingController _passwordController = TextEditingController();
    
      final _formKey = GlobalKey<FormState>();
      final _scaffoldKey = GlobalKey<ScaffoldState>();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          key: _scaffoldKey,
          appBar: AppBar(
            title: Text("Sign up"),
          ),
          body: Form(
            key: _formKey,
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  TextFormField(
                    keyboardType: TextInputType.emailAddress,
                    decoration: InputDecoration(labelText: "Email"),
                    controller: _emailController,
                    validator: (value) =>
                        !validateEmail(value) ? "Email is Invalid" : null,
                  ),
                  TextFormField(
                    keyboardType: TextInputType.visiblePassword,
                    decoration: InputDecoration(labelText: "Password"),
                    obscureText: true,
                    controller: _passwordController,
                    validator: (value) => value.isEmpty
                        ? "Password is invalid"
                        : value.length < 9
                            ? "Password must contain at least 8 characters"
                            : null,
                  ),
                  SizedBox(
                    height: 20,
                  ),
                  RaisedButton(
                      child: Text("CREATE ACCOUNT"),
                      onPressed: () => _createAccountOnPressed(context),
                      color: Theme.of(context).primaryColor,
                      colorBrightness: Theme.of(context).primaryColorBrightness),
                ],
              ),
            ),
          ),
        );
      }
    
      Future<void> _createAccountOnPressed(BuildContext context) async {
        if (_formKey.currentState.validate()) {
          final email = _emailController.text;
          final password = _passwordController.text;
    
          // TODO: Implment sign-up process
    
        }
      }
    
      void _gotToEmailConfirmationScreen(BuildContext context, String email) {
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (_) => EmailConfirmationScreen(email: email),
          ),
        ); 
      }
    }
    
    보시다시피 사용자가 등록 버튼_createAccountOnPressed을 누르면 이 동작을 실행합니다.다음과 같은 방법을 실현합시다.
    Future<void> _createAccountOnPressed(BuildContext context) async {
    
        if (_formKey.currentState.validate()) {
          final email = _emailController.text.trim();
          final password = _passwordController.text;
    
        /// In this user attribute, you can define the custom fields associated with the user.
        /// For example birthday, telephone number, etc
          Map<String, dynamic> userAttributes = {
            "email": email,
          };
    
          try {
            final result = await Amplify.Auth.signUp(
              username: email,
              password: password,
              options: CognitoSignUpOptions(userAttributes: userAttributes),
            );
            if (result.isSignUpComplete) {
              _gotToEmailConfirmationScreen(context, email);
            }
          } on AuthError catch (e) {
            _scaffoldKey.currentState.showSnackBar(
              SnackBar(
                content: Text(e.cause),
              ),
            );
          }
        }
      }
    
  • 우선 컨트롤러로부터 이메일과 비밀번호를 받습니다.
  • 전자메일과 비밀번호 기반 인증을 사용하기 때문에 userAttributes라는 지도를 만들어서 전자메일을 저장해야 합니다.이 지도는 전화번호, 생일 등과 사용자의 증빙서류 등 사용자와 관련된 데이터를 저장하는 데 사용할 수 있다.
  • 그리고 실행 방법Amplify.Auth.signUp은 사용자를 AWS Cognito 사용자 풀에 등록합니다.우리는 전자 우편을 사용자 이름으로 사용합니다.그러나 이 방법에 첨가하는 것을 잊지 마라userAttributes.
  • 오류가 발생하면 SnackBar로 표시합니다.
  • 사용자가 성공적으로 등록되면 AWS는 지정된 이메일에 이메일 확인 코드를 보냅니다.따라서 사용자를 email_confimation_screen라는 새 화면으로 바꿔야 합니다.
  • 구현email_confimation_screen.dart
    import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
    import 'package:amplify_core/amplify_core.dart';
    import 'package:todo_amplify/screens/main_screen.dart';
    import 'package:flutter/material.dart';
    
    class EmailConfirmationScreen extends StatelessWidget {
      final String email;
    
      EmailConfirmationScreen({
        Key key,
        @required this.email,
      }) : super(key: key);
    
      final _scaffoldKey = GlobalKey<ScaffoldState>();
    
      final TextEditingController _confirmationCodeController =
          TextEditingController();
    
      final _formKey = GlobalKey<FormFieldState>();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          key: _scaffoldKey,
          appBar: AppBar(
            title: Text("Confirm your email"),
          ),
          body: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Form(
              child: Column(
                children: [
                  Text(
                    "An email confirmation code is sent to $email. Please type the code to confirm your email.",
                    style: Theme.of(context).textTheme.headline6,
                  ),
                  TextFormField(
                    keyboardType: TextInputType.number,
                    controller: _confirmationCodeController,
                    decoration: InputDecoration(labelText: "Confirmation Code"),
                    validator: (value) => value.length != 6
                        ? "The confirmation code is invalid"
                        : null,
                  ),
                  RaisedButton(
                    onPressed: () => _submitCode(context),
                    child: Text("CONFIRM"),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    
      Future<void> _submitCode(BuildContext context) async {
        if(_formKey.currentState.validate()){
          final confirmationCode = _confirmationCodeController.text;
          // TODO: Submit the code to Amplify
        }
      }
    
      void _gotoMainScreen(BuildContext context) {
        Navigator.push(context, MaterialPageRoute(builder: (_) => MainScreen()));
      }
    }
    
    확인 코드는 6자리 코드입니다.따라서 코드를 확인한 후 다음과 같이 Amplify에 코드를 보낼 수 있습니다.
      Future<void> _submitCode(BuildContext context) async {
        if (_formKey.currentState.validate()) {
          final confirmationCode = _confirmationCodeController.text;
          try {
            final SignUpResult response = await Amplify.Auth.confirmSignUp(
              username: email,
              confirmationCode: confirmationCode,
            );
            if (response.isSignUpComplete) {
              _gotoMainScreen(context);
            }
          } on AuthError catch (e) {
            _scaffoldKey.currentState.showSnackBar(
              SnackBar(
                content: Text(e.cause),
              ),
            );
          }
        }
      }
    
    우리는 Amplify.Auth.confirmSignUp로 이메일을 확인할 수 있다.사용자 이메일 확인 프로세스가 성공적으로 완료되면 기본 화면으로 사용자를 리디렉션할 수 있습니다.
    이제 실현합시다login_screen.dart.
    import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
    import 'package:amplify_core/amplify_core.dart';
    import 'package:todo_amplify/screens/main_screen.dart';
    import 'package:todo_amplify/screens/signup_screen.dart';
    import 'package:todo_amplify/util/email_validator.dart';
    import 'package:flutter/material.dart';
    
    class LoginScreen extends StatelessWidget {
      LoginScreen({Key key}) : super(key: key);
    
      final TextEditingController _emailController = TextEditingController();
      final TextEditingController _passwordController = TextEditingController();
    
      final _formKey = GlobalKey<FormState>();
    
      final _scaffoldKey = GlobalKey<ScaffoldState>();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          key: _scaffoldKey,
          body: Form(
            key: _formKey,
            child: Padding(
              padding: const EdgeInsets.all(50),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  TextFormField(
                    keyboardType: TextInputType.emailAddress,
                    decoration: InputDecoration(labelText: "Email"),
                    controller: _emailController,
                    validator: (value) =>
                        !validateEmail(value) ? "Email is Invalid" : null,
                  ),
                  TextFormField(
                    keyboardType: TextInputType.visiblePassword,
                    decoration: InputDecoration(labelText: "Password"),
                    obscureText: true,
                    controller: _passwordController,
                    validator: (value) =>
                        value.isEmpty ? "Password is invalid" : null,
                  ),
                  SizedBox(
                    height: 20,
                  ),
                  RaisedButton(
                    child: Text("LOG IN"),
                    onPressed: () => _loginButtonOnPressed(context),
                    color: Theme.of(context).primaryColor,
                  ),
                  OutlineButton(
                    child: Text("Create New Account"),
                    onPressed: () => _gotoSignUpScreen(context),
                    color: Theme.of(context).primaryColor,
                  ),
                ],
              ),
            ),
          ),
        );
      }
    
      Future<void> _loginButtonOnPressed(BuildContext context) async {
        if (_formKey.currentState.validate()) {
          //TODO: Login code
        }
      }
    
      void _gotoSignUpScreen(BuildContext context) {
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (_) => SignUpScreen(),
          ),
        );
      }
    }
    
    사용자가 로그인 버튼을 눌렀을 때 _loginButtonOnPressed 실행됩니다.
      Future<void> _loginButtonOnPressed(BuildContext context) async {
        if (_formKey.currentState.validate()) {
          /// Login code
          try {
            final email = _emailController.text.trim();
            final password = _passwordController.text;
    
            final response = await Amplify.Auth.signIn(
              username: email,
              password: password,
            );
    
            if (response.isSignedIn) {
              Navigator.pushReplacement(
                context,
                MaterialPageRoute(
                  builder: (_) => MainScreen(),
                ),
              );
            }
          } on AuthError catch (e) {
            _scaffoldKey.currentState.showSnackBar(
              SnackBar(
                content: Text(e.cause),
              ),
            );
          }
        }
      }
    
    우리는 Amplify.Auth.signIn 방법으로 로그인 요청을 실행할 수 있다.

    좋은 웹페이지 즐겨찾기