Flutter: How to refresh token when token expires with ferry (graphql) client?
421
The way I initialize my ferry client is as follows.
Create a CustomAuthLink that inherits from AuthLink.
import 'package:gql_http_link/gql_http_link.dart'; class _CustomAuthLink extends AuthLink { _CustomAuthLink() : super( getToken: () { // ... // Call your api to refresh the token and return it // ... String token = await ... // api refresh call return "Bearer $token" } ); }
Use this custom auth link to initialise your client.
... final link = Link.from([freshLink, HttpLink('https://.../graphql/')]); ... Client( link: _CustomAuthLink().concat(link), ) ...
I am not sure if you still going to need freshLink anymore. You might wanna remove it and pass
HttpLink(...)
directly into the.concat(...)
method.
Author by
B0r1
Updated on December 01, 2022Comments
-
B0r1 over 1 year
How to retrieve a new token with a refresh token in flutter in a ferry (graphql) client?
The response after a mutation looks like this:
{ "data": { "auth_login": { "access_token": "ey...", "refresh_token": "Ua...", "expires": 900000 } } }
I tried to accomplish it with fresh_graphql, but it does not work. The authenticationStatus is always unauthenticated but the token was always legit.
Implementation:
import 'dart:math'; import 'package:ferry/ferry.dart'; import 'package:ferry_hive_store/ferry_hive_store.dart'; import 'package:fresh_graphql/fresh_graphql.dart'; import 'package:gql_http_link/gql_http_link.dart'; import 'package:hive/hive.dart'; Future<Client> initClient(String? accessToken, String? refreshToken) async { Hive.init('hive_data'); final box = await Hive.openBox<Map<String, dynamic>>('graphql'); await box.clear(); final store = HiveStore(box); final cache = Cache(store: store); final freshLink = await setFreshLink(accessToken ?? '', refreshToken); final link = Link.from( [freshLink, HttpLink('https://.../graphql/')]); final client = Client( link: link, cache: cache, ); return client; } Future<FreshLink> setFreshLink(String accessToken, String? refreshToken) async { final freshLink = FreshLink<dynamic>( tokenStorage: InMemoryTokenStorage<dynamic>(), refreshToken: (dynamic token, client) async { print('refreshing token!'); await Future<void>.delayed(const Duration(seconds: 1)); if (Random().nextInt(1) == 0) { throw RevokeTokenException(); } return OAuth2Token( accessToken: 'top_secret_refreshed', ); }, shouldRefresh: (_) => Random().nextInt(2) == 0, )..authenticationStatus.listen(print); print(freshLink.token); print(freshLink.authenticationStatus); await freshLink .setToken(OAuth2Token(tokenType: 'Bearer', accessToken: accessToken)); return freshLink; }
Any solution, even without fresh_graphql, would be appreciated!
-
Aristidios almost 2 yearsdid you end up using fresh_graphql ? Documentation is quite minimal
-
B0r1 almost 2 yearsYeah you can check the bloc discord group :)
-
Aristidios almost 2 yearsDid you share your implementation on Discord ? Would you mind sharing a link ? : )
-