Flutter:当令牌与渡轮(graphql)客户端过期时如何刷新令牌?
Flutter: How to refresh token when token expires with ferry (graphql) client?
如何在 ferry (graphql) 客户端中使用刷新令牌检索新令牌?
突变后的响应如下所示:
{
"data": {
"auth_login": {
"access_token": "ey...",
"refresh_token": "Ua...",
"expires": 900000
}
}
}
我试图用 fresh_graphql 完成它,但它不起作用。 authenticationStatus 始终未通过身份验证,但令牌始终合法。
实施:
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;
}
任何解决方案,即使没有 fresh_graphql,我们将不胜感激!
我初始化轮渡客户端的方式如下。
创建一个继承自 AuthLink 的 CustomAuthLink。
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"
}
);
}
使用此自定义身份验证 link 初始化您的客户端。
...
final link = Link.from([freshLink, HttpLink('https://.../graphql/')]);
...
Client(
link: _CustomAuthLink().concat(link),
)
...
我不确定您是否还需要 freshLink。您可能想删除它并将 HttpLink(...)
直接传递给 .concat(...)
方法。
如何在 ferry (graphql) 客户端中使用刷新令牌检索新令牌?
突变后的响应如下所示:
{
"data": {
"auth_login": {
"access_token": "ey...",
"refresh_token": "Ua...",
"expires": 900000
}
}
}
我试图用 fresh_graphql 完成它,但它不起作用。 authenticationStatus 始终未通过身份验证,但令牌始终合法。
实施:
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;
}
任何解决方案,即使没有 fresh_graphql,我们将不胜感激!
我初始化轮渡客户端的方式如下。
创建一个继承自 AuthLink 的 CustomAuthLink。
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" } ); }
使用此自定义身份验证 link 初始化您的客户端。
... final link = Link.from([freshLink, HttpLink('https://.../graphql/')]); ... Client( link: _CustomAuthLink().concat(link), ) ...
我不确定您是否还需要 freshLink。您可能想删除它并将
HttpLink(...)
直接传递给.concat(...)
方法。