'How can I add customised header on http request for authentication when using flutter graphql library?
I am using this library https://pub.dev/packages/graphql_flutter for graphql in a flutter web application. Below code can be used to get authentication token:
import 'package:graphql_flutter/graphql_flutter.dart';
final HttpLink httpLink = HttpLink(
'https://api.github.com/graphql',
);
final AuthLink authLink = AuthLink(
getToken: () async => 'Bearer <YOUR_PERSONAL_ACCESS_TOKEN>',
// OR
// getToken: () => 'Bearer <YOUR_PERSONAL_ACCESS_TOKEN>',
);
but how can I put the token in the http header like x-api-key: xxxx
when sending requests?
I have tried:
HttpLink link = HttpLink(
uri: 'https://api.github.com/graphql',
headers: <String, String>{
'x-api-key': 'xxxx',
},
);
but it gives me the error: The named parameter 'uri' isn't defined. Try correcting the name to an existing named parameter's name, or defining a named parameter with the name 'uri'.
Solution 1:[1]
Update: base on the answer from @Moaid
import 'package:graphql_flutter/graphql_flutter.dart';
typedef GetHeaders = FutureOr<Map<String, String>> Function();
class CustomAuthLink extends Link {
CustomAuthLink({
this.getHeaders,
});
final GetHeaders getHeaders;
@override
Stream<Response> request(Request request, [NextLink forward]) {
StreamController<Response> controller;
Future<void> onListen() async {
try {
final Map<String, String> headers = await getHeaders();
return request.updateContextEntry<HttpLinkHeaders>(
(_headers) => HttpLinkHeaders(
headers: <String, String>{
...headers,
},
),
);
} catch (error) {
controller.addError(error);
}
await controller.addStream(forward(request));
await controller.close();
}
controller = StreamController<Response>(onListen: onListen);
return controller.stream;
}
}
Solution 2:[2]
Base on the answer from @moaid-alrazhy and after checking how AuthLink is working
class CustomAuthLink extends Link {
CustomAuthLink();
@override
Stream<Response> request(Request request, [NextLink? forward]) async* {
// Some logic here
final AuthService authService = GetIt.I.get<AuthService>();
final String? token = authService.token;
final String deviceID = await DeviceInformation.deviceIMEINumber;
// TIP: do not forget getting new Request instance!
final Request req = request.updateContextEntry<HttpLinkHeaders>(
(HttpLinkHeaders? headers) => HttpLinkHeaders(
headers: <String, String>{
// put oldest headers
...headers?.headers ?? <String, String>{},
// and add a new headers
'Authorization': 'Bearer $token',
'x-device-id': deviceID,
},
),
);
// and "return" new Request with updated headers
yield* forward!(req);
}
}
Solution 3:[3]
you can add it to your HttpLink like this
HttpLink link = HttpLink(
'https://api.github.com/graphql',
headers: <String, String>{
'x-api-key': 'xxxx',
},
);
however this was in old versions .. now for more headers your have to write your own CustomAuthLink like
typedef GetHeaders = Future<Map<String, String>> Function();
class CustomAuthLink extends Link {
CustomAuthLink({
this.getHeaders,
}) : super(
request: (Operation operation, [NextLink forward]) {
StreamController<FetchResult> controller;
Future<void> onListen() async {
try {
final Map<String, String> headers = await getHeaders();
operation.setContext(<String, Map<String, String>>{
'headers': headers
});
} catch (error) {
controller.addError(error);
}
await controller.addStream(forward(operation));
await controller.close();
}
controller = StreamController<FetchResult>(onListen: onListen);
return controller.stream;
},
);
GetHeaders getHeaders;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | JerryZhou |
Solution 2 | WiRight |
Solution 3 |