Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Secure auth store example #145

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/nhost_dart/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ dependencies:
nhost_graphql_adapter: ^4.0.7
dev_dependencies:
fake_async: ^1.3.1
graphql: ^5.1.3
graphql: ^5.2.0-beta.9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the version upgrade to graphql: ^5.2.0-beta.9 required for the this example ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. I messed up the merging of main branch

lints: any
mockito: ^5.3.2
nock: ^1.2.1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/// This example demonstrates the ability to store authentication tokens between
/// restarts of your application, so that the user is logged in automatically.
///
/// This example depends on the `flutter_secure_storage` package, which is used to
/// implement the [SecureAuthStore] class.
///
/// To try it out, run the application, log in, then restart the app. You should
/// see the contents of [ExampleProtectedScreen] without having to log in a
/// second time.
library secure_persistent_auth_example;

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:nhost_flutter_auth/nhost_flutter_auth.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

import 'config.dart';
import 'simple_auth_example.dart';

void main() {
runApp(const SecurePersistentAuthExample());
}

class SecurePersistentAuthExample extends StatefulWidget {
const SecurePersistentAuthExample({
super.key,
});

@override
SecurePersistentAuthExampleState createState() => SecurePersistentAuthExampleState();
}

class SecurePersistentAuthExampleState extends State<SecurePersistentAuthExample> {
late NhostClient nhostClient;

@override
void initState() {
super.initState();
// Create a new Nhost client using your project's subdomain and region.
nhostClient = NhostClient(
subdomain: Subdomain(
subdomain: subdomain,
region: region,
),
// Instruct the client to store tokens using shared preferences.
authStore: const SecureAuthStore(),
);
// this will fetch refresh token and will sign user in!
nhostClient.auth
.signInWithStoredCredentials()
.then((value) => null)
.catchError(
(e) {
// ignore: avoid_print
print(e);
},
);
}

@override
void dispose() {
super.dispose();
nhostClient.close();
}

@override
Widget build(BuildContext context) {
return NhostAuthProvider(
auth: nhostClient.auth,
child: const MaterialApp(
title: 'Nhost.io Persistent Flutter Authentication Example',
home: Scaffold(
body: ExampleProtectedScreen(),
),
),
);
}
}

/// An Nhost [AuthStore] implementation backed by the `flutter_secure_storage`
/// plugin, so authentication information is retained between runs of the
/// application.
class SecureAuthStore implements AuthStore {
const SecureAuthStore();

@override
Future<String?> getString(String key) {
const FlutterSecureStorage storage = FlutterSecureStorage();
return storage.read(key: key);
}

@override
Future<void> setString(String key, String value) {
const FlutterSecureStorage storage = FlutterSecureStorage();
return storage.write(key: key, value: value);
}

@override
Future<void> removeItem(String key) {
const FlutterSecureStorage storage = FlutterSecureStorage();
return storage.delete(key: key);
}
}
1 change: 1 addition & 0 deletions packages/nhost_flutter_auth/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ dependencies:
provider: '>=6.0.4'
shared_preferences: ^2.0.15
url_launcher: ^6.1.7
flutter_secure_storage: ^9.2.2

# Nhost packages
nhost_flutter_auth:
Expand Down
2 changes: 1 addition & 1 deletion packages/nhost_graphql_adapter/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ environment:
sdk: ">=2.18.0 <4.0.0"

dependencies:
graphql: ^5.1.3
graphql: ^5.2.0-beta.9

# Nhost packages
nhost_dart: ^2.0.7
Expand Down
57 changes: 57 additions & 0 deletions packages/nhost_graphql_adapter/lib/src/create_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,54 @@ import '../nhost_graphql_adapter.dart';
/// requests made by the Nhost APIs, which can be useful for proxy configuration
/// and debugging.
/// {@endtemplate}
///
/// {@template nhost.graphqlClient.defaultPolicies}
/// [defaultPolicies] (optional) customizes the default policies used by the
/// client. This can be used to change the cache-and-network or network-only
/// behavior of the client.
/// {@endtemplate}
///
/// {@template nhost.graphqlClient.alwaysRebroadcast}
/// [alwaysRebroadcast] (optional) if true, the client will rebroadcast watch
/// queries when the underlying cache changes. This is false by default.
/// {@endtemplate}
///
/// {@template nhost.graphqlClient.deepEquals}
/// [deepEquals] (optional) overrides the default deep equals comparison for
/// caching.
/// {@endtemplate}
///
/// {@template nhost.graphqlClient.deduplicatePollers}
/// [deduplicatePollers] (optional) if true, the client will deduplicate
/// duplicate pollers. This is true by default.
/// {@endtemplate}
///
/// {@template nhost.graphqlClient.queryRequestTimeout}
/// [queryRequestTimeout] (optional) overrides the default request timeout for
/// queries. This is 10 seconds by default.
/// {@endtemplate}
GraphQLClient createNhostGraphQLClient(
NhostClientBase nhostClient, {
GraphQLCache? gqlCache,
Map<String, String>? defaultHeaders,
http.Client? httpClientOverride,
DefaultPolicies? defaultPolicies,
bool? alwaysRebroadcast,
DeepEqualsFn? deepEquals,
bool? deduplicatePollers,
Duration? queryRequestTimeout,
}) {
return createNhostGraphQLClientForAuth(
nhostClient.gqlEndpointUrl,
nhostClient.auth,
gqlCache: gqlCache,
defaultHeaders: defaultHeaders,
httpClientOverride: httpClientOverride,
defaultPolicies: defaultPolicies,
alwaysRebroadcast: alwaysRebroadcast,
deepEquals: deepEquals,
deduplicatePollers: deduplicatePollers,
queryRequestTimeout: queryRequestTimeout,
);
}

Expand All @@ -52,12 +88,28 @@ GraphQLClient createNhostGraphQLClient(
/// {@macro nhost.graphqlClient.defaultHeaders}
///
/// {@macro nhost.graphqlClient.httpClientOverride}
///
/// {@macro nhost.graphqlClient.defaultPolicies}
///
/// {@macro nhost.graphqlClient.alwaysRebroadcast}
///
/// {@macro nhost.graphqlClient.deepEquals}
///
/// {@macro nhost.graphqlClient.deduplicatePollers}
///
/// {@macro nhost.graphqlClient.queryRequestTimeout}
///
GraphQLClient createNhostGraphQLClientForAuth(
String nhostGqlEndpointUrl,
HasuraAuthClient nhostAuth, {
GraphQLCache? gqlCache,
Map<String, String>? defaultHeaders,
http.Client? httpClientOverride,
DefaultPolicies? defaultPolicies,
bool? alwaysRebroadcast,
DeepEqualsFn? deepEquals,
bool? deduplicatePollers,
Duration? queryRequestTimeout,
}) {
return GraphQLClient(
link: combinedLinkForNhostAuth(
Expand All @@ -67,5 +119,10 @@ GraphQLClient createNhostGraphQLClientForAuth(
httpClientOverride: httpClientOverride,
),
cache: gqlCache ?? GraphQLCache(),
defaultPolicies: defaultPolicies,
alwaysRebroadcast: alwaysRebroadcast ?? false,
deepEquals: deepEquals,
deduplicatePollers: deduplicatePollers ?? false,
queryRequestTimeout: queryRequestTimeout ?? const Duration(seconds: 5),
);
}
2 changes: 1 addition & 1 deletion packages/nhost_graphql_adapter/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ environment:
sdk: ">=2.14.0 <4.0.0"

dependencies:
graphql: ^5.1.3
graphql: ^5.2.0-beta.9
http: ^1.1.0
meta: ^1.7.0

Expand Down
2 changes: 1 addition & 1 deletion packages/nhost_sdk/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ dependencies:

dev_dependencies:
fake_async: ^1.3.1
graphql: ^5.1.3
graphql: ^5.2.0-beta.9
lints: any
mockito: ^5.3.2
nock: ^1.2.1
Expand Down