Add Bot Detection to Native Applications

If you build native applications using an Auth0 SDK for the login flow, you can enable Bot Detection to render a CAPTCHA step in scenarios when a login request is determined by Auth0 to be high-risk. Your custom login form code must handle scenarios where the user is asked to pass a CAPTCHA step. If you don't account for this scenario, your application may cause an error.

Auth0.Swift and Auth0.Android

If you use Universal Login, Bot Detection is supported automatically with the following SDK versions:

  • Auth0.Swift version 1.28.0

  • Auth0.Android version 1.25.0

If you prompt for credentials in your application using the password grant flow:

  • A high-risk login will trigger an exception of the type requires_verification.

  • Your code must handle this exception by triggering a webauth flow, which will render a CAPTCHA step.

  • You may pass login_hint when triggering the web flow, so that a user going through the experience does not have to type in their username again.

Auth0.Swift example

If you are using Bot Detection and performing database login/signup via the Authentication API, you need to handle the isVerificationRequired error. It indicates that the request was flagged as suspicious and an additional verification step is necessary to log the user in. That verification step is web-based, so you need to use Universal Login to complete it.

let email = "username@domain.com"
let realm = "Username-Password-Authentication"
let scope = "openid profile"

Auth0
    .authentication()
    .login(usernameOrEmail: email,
           password: "secret-password",
           realm: realm,
           scope: scope)
     .start { result in
         switch result {
         case .success(let credentials):
            print("Obtained credentials: \(credentials)")
         case .failure(let error as AuthenticationError) where error.isVerificationRequired:
            DispatchQueue.main.async {
                Auth0
                    .webAuth()
                    .connection(realm)
                    .scope(scope)
                    .parameters(["login_hint": email])
                    // ☝🏼 So the user doesn't have to type it again
                    .start { result in
                        // Handle result
                    }
            }
         case .failure(let error):
            print("Failed with \(error)")
         }
     }

In the case of signup, you can add an additional parameter to make the user land directly on the signup page:

.parameters(["login_hint": email, "screen_hint": "signup"])

See Auth0.Swift Getting Started for details on how to set up Universal Login. You don't need to handle this error if you're using the deprecated login methods.

Auth0.Android example

If you are using Bot Protection and performing database login/signup using the Authentication API, you must handle the AuthenticationException#isVerificationRequired() error. It indicates that the request was flagged as suspicious and an additional verification step is necessary to log the user in. That verification step is web-based, so you need to use Universal Login to complete it.

final String email = "username@domain.com";
final String password = "a secret password";
final String realm = "my-database-connection";

AuthenticationAPIClient authentication = new AuthenticationAPIClient(account);
authentication.login(email, password, realm)
        .start(new BaseCallback<Credentials, AuthenticationException>() {

            @Override
            public void onFailure(AuthenticationException error) {
                if (error.isVerificationRequired()){
                    Map<String, Object> params = new HashMap<>();
                    params.put("login_hint", email); // So the user doesn't have to type it again
                    WebAuthProvider.login(account)
                            .withConnection(realm)
                            .withParameters(params)
                            .start(LoginActivity.this, new AuthCallback() {
                                // You might already have an AuthCallback instance defined

                                @Override
                                public void onFailure(@NonNull Dialog dialog) {
                                    // Error dialog available
                                }

                                @Override
                                public void onFailure(AuthenticationException exception) {
                                    // Error
                                }

                                @Override
                                public void onSuccess(@NonNull Credentials credentials) {
                                    // Handle WebAuth success
                                }
                            });
                }
            }

            @Override
            public void onSuccess(Credentials payload) {
                // Handle API success
            }
        });

In the case of signup, you can add an additional parameter to make the user land directly on the signup page:

params.put("screen_hint", "signup");

See Auth0.Android Authentication with Universal Login SDK documentation for details on how to set up Universal Login.

Lock.Swift and Lock.Android

Bot Detection is supported by the following SDK versions:

  • Lock.Swift version 2.19.0

  • Lock.Android version 2.22.0

If you prompt for credentials in your application using the password grant flow:

  • A high-risk login will open a browser automatically and use it to render a CAPTCHA step.

  • Configure your application to allow authentication with Universal Login to trigger the CAPTCHA in high-risk scenarios. See Universal Login for Android or Universal Login for Swift.

Learn more