signIn method

Future<SignInResult> signIn({
  1. required String username,
  2. String? password,
  3. SignInOptions? options,
})

Initiate sign in for user with username and optional password.

Optionally accepts plugin options which allow customizing provider-specific behavior, e.g. the Cognito User Pool.

For more information, see the Amplify docs.

Examples

For Cognito flows, including a password will initiate an SRP sign-in, while excluding the password will initiate a custom auth sign-in.

import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
Future<void> signInUser(String username, String password) async {
  try {
    final result = await Amplify.Auth.signIn(
      username: username,
      password: password,
    );
    return _handleSignInResult(result);
  } on AuthException catch (e) {
    safePrint('Error signing in: ${e.message}');
  }
}
Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ···
  }
}

If SMS MFA is enabled, prompt the user to check their phone for a code.

Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ···
    case AuthSignInStep.confirmSignInWithSmsMfaCode:
      final codeDeliveryDetails = result.nextStep.codeDeliveryDetails!;
      _handleCodeDelivery(codeDeliveryDetails);
    // ···
  }
}
void _handleCodeDelivery(AuthCodeDeliveryDetails codeDeliveryDetails) {
  safePrint(
    'A confirmation code has been sent to ${codeDeliveryDetails.destination}. '
    'Please check your ${codeDeliveryDetails.deliveryMedium.name} for the code.',
  );
}

If TOTP MFA is enabled, prompt the user to visit their registered authenticator app for a one-time code.

Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ···
    case AuthSignInStep.confirmSignInWithTotpMfaCode:
      safePrint('Enter a one-time code from your registered Authenticator app');
    // ···
  }
}

If TOTP MFA is enabled but the user has not configured it yet, prompt them to install an authenticator app capable of generating one-time passcodes (e.g. Google Authenticator or Microsoft Authenticator), then use the returned TotpSetupDetails to generate and display a URI for setup.

Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ···
    case AuthSignInStep.continueSignInWithTotpSetup:
      final totpSetupDetails = result.nextStep.totpSetupDetails!;
      final setupUri = totpSetupDetails.getSetupUri(appName: 'MyApp');
      safePrint('Open URI to complete setup: $setupUri');
    // ···
  }
}

If both SMS MFA and TOTP MFA are enabled and configured for the user, they will be given the choice of which mechanism they'd like to use to continue signing in.

Future<MfaType> _promptUserPreference(Set<MfaType> allowedTypes) async {
  // ···
}
Future<void> _handleMfaSelection(MfaType selection) async {
  try {
    final result = await Amplify.Auth.confirmSignIn(
      confirmationValue: selection.confirmationValue,
    );
    return _handleSignInResult(result);
  } on AuthException catch (e) {
    safePrint('Error resending code: ${e.message}');
  }
}
Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ···
    case AuthSignInStep.continueSignInWithMfaSelection:
      final allowedMfaTypes = result.nextStep.allowedMfaTypes!;
      final selection = await _promptUserPreference(allowedMfaTypes);
      return _handleMfaSelection(selection);
    // ···
  }
}

If the user was created by an administrator, a new password will be required. Prompt the user to choose a new password and pass the value to confirmSignIn.

Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ···
    case AuthSignInStep.confirmSignInWithNewPassword:
      safePrint('Enter a new password to continue signing in');
    // ···
  }
}

If you've implemented a custom auth flow, the SignInResult will include the parameters of your challenge in the additionalInfo field. These parameters can be used to relay any information from your backend code which can be used to customize the flow however you'd like.

Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ···
    case AuthSignInStep.confirmSignInWithCustomChallenge:
      final parameters = result.nextStep.additionalInfo;
      final prompt = parameters['prompt']!;
      safePrint(prompt);
    // ···
  }
}

If the user is required to reset their password before continuing, use the resetPassword API to initiate a password and follow the instructions to confirm the reset if necessary.

Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ···
    case AuthSignInStep.resetPassword:
      final resetResult = await Amplify.Auth.resetPassword(
        username: username,
      );
      await _handleResetPasswordResult(resetResult);
    // ···
  }
}
Future<void> _handleResetPasswordResult(ResetPasswordResult result) async {
  switch (result.nextStep.updateStep) {
    case AuthResetPasswordStep.confirmResetPasswordWithCode:
      final codeDeliveryDetails = result.nextStep.codeDeliveryDetails!;
      _handleCodeDelivery(codeDeliveryDetails);
    case AuthResetPasswordStep.done:
      safePrint('Successfully reset password');
  }
}

If a user tries to sign in before completing their sign up, the AuthSignInStep.confirmSignUp step will be returned. This is the same step returned from signUp and requires a call to confirmSignUp before re-initiating the sign in flow.

Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ···
    case AuthSignInStep.confirmSignUp:
      // Resend the sign up code to the registered device.
      final resendResult = await Amplify.Auth.resendSignUpCode(
        username: username,
      );
      _handleCodeDelivery(resendResult.codeDeliveryDetails);
    // ···
  }
}
void _handleCodeDelivery(AuthCodeDeliveryDetails codeDeliveryDetails) {
  safePrint(
    'A confirmation code has been sent to ${codeDeliveryDetails.destination}. '
    'Please check your ${codeDeliveryDetails.deliveryMedium.name} for the code.',
  );
}

When there are no more challenges and the sign in is complete, the next step will be AuthSignInStep.done.

Future<void> _handleSignInResult(SignInResult result) async {
  switch (result.nextStep.signInStep) {
    // ···
    case AuthSignInStep.done:
      safePrint('Sign in is complete');
    // ···
  }
}

Implementation

Future<SignInResult> signIn({
  required String username,
  String? password,
  SignInOptions? options,
}) =>
    identifyCall(
      AuthCategoryMethod.signIn,
      () => defaultPlugin.signIn(
        username: username,
        password: password,
        options: options,
      ),
    );