pub-web.flutter-io.cn Open in urlscan Pro
2606:4700:3030::6815:d0d  Public Scan

URL: https://pub-web.flutter-io.cn/packages/flutter_appauth
Submission Tags: falconsandbox
Submission: On November 05 via api from US — Scanned from US

Form analysis 1 forms found in the DOM

GET /packages

<form action="/packages" method="GET"><input class="site-header-search-input" name="q" placeholder="New search..." autocomplete="on" title="Search"></form>

Text Content

Help


PUB.DEV

Searching for packagesPackage scoring and pub points


FLUTTER

Using packagesDeveloping packages and pluginsPublishing a package


DART

Using packagesPublishing a package


PUB.DEV

Searching for packagesPackage scoring and pub points


FLUTTER

Using packagesDeveloping packages and pluginsPublishing a package


DART

Using packagesPublishing a package



FLUTTER_APPAUTH 8.0.0+1
FLUTTER_APPAUTH: ^8.0.0+1 COPIED TO CLIPBOARD

Published 11 days ago • dexterx.devDart 3 compatible
SDKFlutter
PlatformAndroidiOSmacOS
363
→


METADATA

This plugin provides an abstraction around the Android and iOS AppAuth SDKs so
it can be used to communicate with OAuth 2.0 and OpenID Connect providers

More...

 * Readme
 * Changelog
 * Example
 * Installing
 * Versions
 * Scores


FLUTTER APPAUTH PLUGIN #



A Flutter bridge for AppAuth (https://appauth.io) used authenticating and
authorizing users. Note that AppAuth also supports the PKCE extension that is
required some providers so this plugin should work with them.

IMPORTANT NOTES:

 * This plugin requires apps to be using AndroidX. The Flutter tooling supports
   creating apps with AndroidX support but requires passing the androidx flag.
   Details on AndroidX compatibility and migration can be found here
 * If Chrome Custom Tabs are not working in your Android app, check to make sure
   that you have the latest version of this plugin, Android Studio, Gradle
   distribution and Android Gradle plugin for your app. There was previously a
   known issue with the Android tooling with AndroidX that should now be
   resolved since Android Studio 3.4 has been released


TUTORIALS FROM IDENTITY PROVIDERS #

 * Asgardeo
 * Auth0
 * FusionAuth


GETTING STARTED #

Please see the example that demonstrates how to sign into the demo
IdentityServer instance (https://demo.duendesoftware.com). It has also been
tested with Azure B2C, Auth0, FusionAuth and Google Sign-in. Developers should
check the documentation of the identity provider they are using to see what
capabilities it supports (e.g. how to logout, what values of the prompt
parameter it supports etc) and how to configure/register their application with
the identity provider. Understanding OAuth 2.0 is also essential, especially
when it comes to best practices for native mobile apps.

The first step is to create an instance of the plugin

FlutterAppAuth appAuth = FlutterAppAuth();



copied to clipboard

Afterwards, you'll reach a point where end-users need to be authorized and
authenticated. A convenience method is provided that will perform an
authorization request and automatically exchange the authorization code. This
can be done in a few different ways, one of which is to use the OpenID Connect
Discovery

final AuthorizationTokenResponse result = await appAuth.authorizeAndExchangeCode(
                    AuthorizationTokenRequest(
                      '<client_id>',
                      '<redirect_url>',
                      discoveryUrl: '<discovery_url>',
                      scopes: ['openid','profile', 'email', 'offline_access', 'api'],
                    ),
                  );



copied to clipboard

Here the <client_id> and <redirect_url> should be replaced by the values
registered with your identity provider. The <discovery_url> would be the URL for
the discovery endpoint exposed by your provider that will return a document
containing information about the OAuth 2.0 endpoints among other things. This
URL is obtained by concatenating the issuer with the path
/.well-known/openid-configuration. For example, the full URL for the
IdentityServer instance is
https://demo.duendesoftware.com/.well-known/openid-configuration. As
demonstrated in the above sample code, it's also possible specify the scopes
being requested.

Rather than using the full discovery URL, the issuer could be used instead so
that the process retrieving the discovery document is skipped

final AuthorizationTokenResponse result = await appAuth.authorizeAndExchangeCode(
                    AuthorizationTokenRequest(
                      '<client_id>',
                      '<redirect_url>',
                      issuer: '<issuer>',
                      scopes: ['openid','profile', 'email', 'offline_access', 'api'],
                    ),
                  );



copied to clipboard

In the event that discovery isn't supported or that you already know the
endpoints for your server, they could be explicitly specified

final AuthorizationTokenResponse result = await appAuth.authorizeAndExchangeCode(
                    AuthorizationTokenRequest(
                      '<client_id>',
                      '<redirect_url>',
                      serviceConfiguration: AuthorizationServiceConfiguration(authorizationEndpoint: '<authorization_endpoint>',  tokenEndpoint: '<token_endpoint>', endSessionEndpoint: '<end_session_endpoint>'),
                      scopes: [...]
                    ),
                  );



copied to clipboard

Upon completing the request successfully, the method should return an object
(the result variable in the above sample code is an instance of the
AuthorizationTokenResponse class) that contain details that should be stored for
future use e.g. access token, refresh token etc.

If you would prefer to not have the automatic code exchange to happen then can
call the authorize method instead of the authorizeAndExchangeCode method. This
will return an instance of the AuthorizationResponse class that will contain the
nonce value and code verifier (note: code verifier is used as part of implement
PKCE) that AppAuth generated when issuing the authorization request, the
authorization code and additional parameters should they exist. The nonce, code
verifier and authorization code would need to be stored so they can then be
reused to exchange the code later on e.g.

final TokenResponse result = await appAuth.token(TokenRequest('<client_id>', '<redirect_url>',
        authorizationCode: '<authorization_code>',
        discoveryUrl: '<discovery_url>',
        codeVerifier: '<code_verifier>',
        nonce: 'nonce',
        scopes: ['openid','profile', 'email', 'offline_access', 'api']));



copied to clipboard

Reusing the nonce and code verifier is particularly important as the AppAuth
SDKs (especially on Android) may return an error (e.g. ID token validation error
due to nonce mismatch) if this isn't done


DETECTING USER CANCELLATION #

Both the authorize and authorizeAndExchangeCode launch the user into a browser
which they can cancel. This shouldn't be considered an error and should be
handled gracefully.

try {
  await appAuth.authorize(...); // Or authorizeAndExchangeCode(...)
} on FlutterAppAuthUserCancelledException catch (e) {
  // Handle user cancellation
}



copied to clipboard


REFRESHING TOKENS #

Some providers may return a refresh token that could be used to refresh
short-lived access tokens. A request to get a new access token before it expires
could be made that would like similar to the following code

final TokenResponse result = await appAuth.token(TokenRequest('<client_id>', '<redirect_url>',
        discoveryUrl: '<discovery_url>',
        refreshToken: '<refresh_token>',
        scopes: ['openid','profile', 'email', 'offline_access', 'api']));



copied to clipboard


END SESSION #

If your server has an end session endpoint, you can trigger an end session
request that is typically used for logging out of the built-in browser with code
similar to what's shown below

await appAuth.endSession(EndSessionRequest(
          idTokenHint: '<idToken>',
          postLogoutRedirectUrl: '<postLogoutRedirectUrl>',
          serviceConfiguration: AuthorizationServiceConfiguration(authorizationEndpoint: '<authorization_endpoint>',  tokenEndpooint: '<token_endpoint>', endSessionEndpoint: '<end_session_endpoint>'));



copied to clipboard

The above code passes an AuthorizationServiceConfiguration with all the
endpoints defined but alternatives are to specify an issuer or discoveryUrl like
you would with the other APIs in the plugin (e.g. authorizeAndExchangeCode()).


HANDLING ERRORS #

Each of these methods will throw exceptions if anything goes wrong. For example:


try {
  await appAuth.authorize(...);
} on FlutterAppAuthPlatformException catch (e) {
  final FlutterAppAuthPlatformErrorDetails details = e.details;
  // Handle exceptions based on errors from AppAuth.
} catch (e) {
  // Handle other errors.
}

The `FlutterAppAuthPlatformErrorDetails` object contains all the error information from the underlying platform's AppAuth SDK.

This includes the error codes specified in the [RFC](https://datatracker.ietf.org/doc/html/rfc6749#section-5.2).




copied to clipboard


EPHEMERAL SESSIONS (IOS AND MACOS ONLY) #

On iOS (versions 13 and above) and macOS you can use the option
preferEphemeralSession = true to start an ephemeral browser session to sign in
and sign out.

With an ephemeral session there will be no warning like "app_name" Wants to Use
"domain_name" to Sign In on iOS.

The option preferEphemeralSession = true must only be used for the end session
call if it is also used for the sign in call. Otherwise, there will be still an
active login session in the browser.


ANDROID SETUP #

Go to the build.gradle file for your Android app to specify the custom scheme so
that there should be a section in it that look similar to the following but
replace <your_custom_scheme> with the desired value

...groovy
android {
    ...
    defaultConfig {
        ...
        manifestPlaceholders += [
                'appAuthRedirectScheme': '<your_custom_scheme>'
        ]
    }
}



copied to clipboard

Alternatively, the redirect URI can be directly configured by adding an
intent-filter for AppAuth's RedirectUriReceiverActivity to your
AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.my_app">
...
<activity
        android:name="net.openid.appauth.RedirectUriReceiverActivity"
        android:theme="@style/Theme.AppCompat.Translucent.NoTitleBar"
        android:exported="true"
        tools:node="replace">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="<your_custom_scheme>"
              android:host="<your_custom_host>"/>
    </intent-filter>
</activity>
...



copied to clipboard

Please ensure that value of <your_custom_scheme> is all in lowercase as there've
been reports from the community who had issues with redirects if there were any
capital letters. You may also notice the += operation is applied on
manifestPlaceholders instead of =. This is intentional and required as newer
versions of the Flutter SDK has made some changes underneath the hood to deal
with multidex. Using = instead of += can lead to errors like the following

Attribute application@name at AndroidManifest.xml:5:9-42 requires a placeholder substitution but no value for <applicationName> is provided.



copied to clipboard

If you see this error then update your build.gradle to use += instead.


IOS/MACOS SETUP #

Go to the Info.plist for your iOS/macOS app to specify the custom scheme so that
there should be a section in it that look similar to the following but replace
<your_custom_scheme> with the desired value

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string><your_custom_scheme></string>
        </array>
    </dict>
</array>



copied to clipboard

Note: iOS apps generate a file called cache.db which contains the table
cfurl_cache_receiver_data. This table will contain the access token obtained
after the login is completed. If the potential data leak represents a threat for
your application then you can disable the information caching for the entire iOS
app (ex.
https://kunalgupta1508.medium.com/data-leakage-with-cache-db-2d311582cf23).


API DOCS #

API docs can be found here


FAQS #

When connecting to Azure B2C or Azure AD, the login request redirects properly
on Android but not on iOS. What's going on?

The AppAuth iOS SDK has some logic to validate the redirect URL to see if it
should be responsible for processing the redirect. This appears to be failing
under certain circumstances. Adding a trailing slash to the redirect URL
specified in your code has been reported to fix the issue.

363
likes
160
pub points
98%
popularity



PUBLISHER

dexterx.dev


METADATA

This plugin provides an abstraction around the Android and iOS AppAuth SDKs so
it can be used to communicate with OAuth 2.0 and OpenID Connect providers

Repository (GitHub)
View/report issues
Contributing



DOCUMENTATION

API reference



LICENSE

BSD-3-Clause (license)


DEPENDENCIES

flutter, flutter_appauth_platform_interface


MORE

Packages that depend on flutter_appauth


← METADATA

363
likes
160
pub points
98%
popularity



PUBLISHER

dexterx.dev


METADATA

This plugin provides an abstraction around the Android and iOS AppAuth SDKs so
it can be used to communicate with OAuth 2.0 and OpenID Connect providers

Repository (GitHub)
View/report issues
Contributing



DOCUMENTATION

API reference



LICENSE

BSD-3-Clause (license)


DEPENDENCIES

flutter, flutter_appauth_platform_interface


MORE

Packages that depend on flutter_appauth

Back



Dart languageReport packagePolicyTermsAPI
TermsSecurityPrivacyHelp豫ICP备18021312号-1