mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 02:39:19 +08:00
feat: implement authentication handling in HTTP requests
This commit is contained in:
@@ -318,6 +318,8 @@ class CollectionStateNotifier
|
|||||||
var responseRec = await sendHttpRequest(
|
var responseRec = await sendHttpRequest(
|
||||||
requestId,
|
requestId,
|
||||||
apiType,
|
apiType,
|
||||||
|
requestModel.authData,
|
||||||
|
requestModel.authType,
|
||||||
substitutedHttpRequestModel,
|
substitutedHttpRequestModel,
|
||||||
defaultUriScheme: defaultUriScheme,
|
defaultUriScheme: defaultUriScheme,
|
||||||
noSSL: noSSL,
|
noSSL: noSSL,
|
||||||
|
|||||||
76
packages/apidash_core/lib/utils/handle_auth.dart
Normal file
76
packages/apidash_core/lib/utils/handle_auth.dart
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'package:apidash_core/consts.dart';
|
||||||
|
import 'package:apidash_core/models/api_auth_model.dart';
|
||||||
|
import 'package:apidash_core/models/http_request_model.dart';
|
||||||
|
import 'package:seed/seed.dart';
|
||||||
|
|
||||||
|
HttpRequestModel handleAuth(HttpRequestModel httpRequestModel,
|
||||||
|
APIAuthType apiAuthType, APIAuthModel? authData) {
|
||||||
|
if (authData == null || apiAuthType == APIAuthType.none) {
|
||||||
|
return httpRequestModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<NameValueModel> updatedHeaders = List.from(httpRequestModel.headers ?? []);
|
||||||
|
List<NameValueModel> updatedParams = List.from(httpRequestModel.params ?? []);
|
||||||
|
List<bool> updatedHeaderEnabledList = List.from(httpRequestModel.isHeaderEnabledList ?? []);
|
||||||
|
List<bool> updatedParamEnabledList = List.from(httpRequestModel.isParamEnabledList ?? []);
|
||||||
|
|
||||||
|
switch (apiAuthType) {
|
||||||
|
case APIAuthType.basic:
|
||||||
|
final auth = authData as BasicAuth;
|
||||||
|
final encoded =
|
||||||
|
base64Encode(utf8.encode('${auth.username}:${auth.password}'));
|
||||||
|
updatedHeaders.add(const NameValueModel(name: 'Authorization', value: ''));
|
||||||
|
updatedHeaders[updatedHeaders.length - 1] = NameValueModel(
|
||||||
|
name: 'Authorization',
|
||||||
|
value: 'Basic $encoded'
|
||||||
|
);
|
||||||
|
updatedHeaderEnabledList.add(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case APIAuthType.bearerToken:
|
||||||
|
final auth = authData as BearerTokenAuth;
|
||||||
|
updatedHeaders.add(NameValueModel(
|
||||||
|
name: 'Authorization',
|
||||||
|
value: 'Bearer ${auth.token}'
|
||||||
|
));
|
||||||
|
updatedHeaderEnabledList.add(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case APIAuthType.jwtBearer:
|
||||||
|
final auth = authData as JWTBearerAuth;
|
||||||
|
updatedHeaders.add(NameValueModel(
|
||||||
|
name: 'Authorization',
|
||||||
|
value: 'Bearer ${auth.jwt}'
|
||||||
|
));
|
||||||
|
updatedHeaderEnabledList.add(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case APIAuthType.apiKey:
|
||||||
|
final auth = authData as APIKeyAuth;
|
||||||
|
if (auth.location == 'header') {
|
||||||
|
updatedHeaders.add(NameValueModel(
|
||||||
|
name: auth.name,
|
||||||
|
value: auth.key
|
||||||
|
));
|
||||||
|
updatedHeaderEnabledList.add(true);
|
||||||
|
} else if (auth.location == 'query') {
|
||||||
|
updatedParams.add(NameValueModel(
|
||||||
|
name: auth.name,
|
||||||
|
value: auth.key
|
||||||
|
));
|
||||||
|
updatedParamEnabledList.add(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpRequestModel.copyWith(
|
||||||
|
headers: updatedHeaders,
|
||||||
|
params: updatedParams,
|
||||||
|
isHeaderEnabledList: updatedHeaderEnabledList,
|
||||||
|
isParamEnabledList: updatedParamEnabledList,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import '../consts.dart';
|
|||||||
import '../extensions/extensions.dart';
|
import '../extensions/extensions.dart';
|
||||||
import '../models/models.dart';
|
import '../models/models.dart';
|
||||||
import '../utils/utils.dart';
|
import '../utils/utils.dart';
|
||||||
|
import '../utils/handle_auth.dart';
|
||||||
import 'http_client_manager.dart';
|
import 'http_client_manager.dart';
|
||||||
|
|
||||||
typedef HttpResponse = http.Response;
|
typedef HttpResponse = http.Response;
|
||||||
@@ -16,6 +17,8 @@ final httpClientManager = HttpClientManager();
|
|||||||
Future<(HttpResponse?, Duration?, String?)> sendHttpRequest(
|
Future<(HttpResponse?, Duration?, String?)> sendHttpRequest(
|
||||||
String requestId,
|
String requestId,
|
||||||
APIType apiType,
|
APIType apiType,
|
||||||
|
APIAuthModel? authData,
|
||||||
|
APIAuthType apiAuthType,
|
||||||
HttpRequestModel requestModel, {
|
HttpRequestModel requestModel, {
|
||||||
SupportedUriSchemes defaultUriScheme = kDefaultUriScheme,
|
SupportedUriSchemes defaultUriScheme = kDefaultUriScheme,
|
||||||
bool noSSL = false,
|
bool noSSL = false,
|
||||||
@@ -25,15 +28,19 @@ Future<(HttpResponse?, Duration?, String?)> sendHttpRequest(
|
|||||||
}
|
}
|
||||||
final client = httpClientManager.createClient(requestId, noSSL: noSSL);
|
final client = httpClientManager.createClient(requestId, noSSL: noSSL);
|
||||||
|
|
||||||
|
// Handle authentication
|
||||||
|
final authenticatedRequestModel =
|
||||||
|
handleAuth(requestModel, apiAuthType, authData);
|
||||||
|
|
||||||
(Uri?, String?) uriRec = getValidRequestUri(
|
(Uri?, String?) uriRec = getValidRequestUri(
|
||||||
requestModel.url,
|
authenticatedRequestModel.url,
|
||||||
requestModel.enabledParams,
|
authenticatedRequestModel.enabledParams,
|
||||||
defaultUriScheme: defaultUriScheme,
|
defaultUriScheme: defaultUriScheme,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (uriRec.$1 != null) {
|
if (uriRec.$1 != null) {
|
||||||
Uri requestUrl = uriRec.$1!;
|
Uri requestUrl = uriRec.$1!;
|
||||||
Map<String, String> headers = requestModel.enabledHeadersMap;
|
Map<String, String> headers = authenticatedRequestModel.enabledHeadersMap;
|
||||||
bool overrideContentType = false;
|
bool overrideContentType = false;
|
||||||
HttpResponse? response;
|
HttpResponse? response;
|
||||||
String? body;
|
String? body;
|
||||||
@@ -43,26 +50,26 @@ Future<(HttpResponse?, Duration?, String?)> sendHttpRequest(
|
|||||||
var isMultiPartRequest =
|
var isMultiPartRequest =
|
||||||
requestModel.bodyContentType == ContentType.formdata;
|
requestModel.bodyContentType == ContentType.formdata;
|
||||||
|
|
||||||
if (kMethodsWithBody.contains(requestModel.method)) {
|
if (kMethodsWithBody.contains(authenticatedRequestModel.method)) {
|
||||||
var requestBody = requestModel.body;
|
var requestBody = authenticatedRequestModel.body;
|
||||||
if (requestBody != null &&
|
if (requestBody != null &&
|
||||||
!isMultiPartRequest &&
|
!isMultiPartRequest &&
|
||||||
requestBody.isNotEmpty) {
|
requestBody.isNotEmpty) {
|
||||||
body = requestBody;
|
body = requestBody;
|
||||||
if (requestModel.hasContentTypeHeader) {
|
if (authenticatedRequestModel.hasContentTypeHeader) {
|
||||||
overrideContentType = true;
|
overrideContentType = true;
|
||||||
} else {
|
} else {
|
||||||
headers[HttpHeaders.contentTypeHeader] =
|
headers[HttpHeaders.contentTypeHeader] =
|
||||||
requestModel.bodyContentType.header;
|
authenticatedRequestModel.bodyContentType.header;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isMultiPartRequest) {
|
if (isMultiPartRequest) {
|
||||||
var multiPartRequest = http.MultipartRequest(
|
var multiPartRequest = http.MultipartRequest(
|
||||||
requestModel.method.name.toUpperCase(),
|
authenticatedRequestModel.method.name.toUpperCase(),
|
||||||
requestUrl,
|
requestUrl,
|
||||||
);
|
);
|
||||||
multiPartRequest.headers.addAll(headers);
|
multiPartRequest.headers.addAll(headers);
|
||||||
for (var formData in requestModel.formDataList) {
|
for (var formData in authenticatedRequestModel.formDataList) {
|
||||||
if (formData.type == FormDataType.text) {
|
if (formData.type == FormDataType.text) {
|
||||||
multiPartRequest.fields.addAll({formData.name: formData.value});
|
multiPartRequest.fields.addAll({formData.name: formData.value});
|
||||||
} else {
|
} else {
|
||||||
@@ -84,7 +91,7 @@ Future<(HttpResponse?, Duration?, String?)> sendHttpRequest(
|
|||||||
return (convertedMultiPartResponse, stopwatch.elapsed, null);
|
return (convertedMultiPartResponse, stopwatch.elapsed, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (requestModel.method) {
|
switch (authenticatedRequestModel.method) {
|
||||||
case HTTPVerb.get:
|
case HTTPVerb.get:
|
||||||
response = await client.get(requestUrl, headers: headers);
|
response = await client.get(requestUrl, headers: headers);
|
||||||
break;
|
break;
|
||||||
@@ -98,7 +105,7 @@ Future<(HttpResponse?, Duration?, String?)> sendHttpRequest(
|
|||||||
case HTTPVerb.options:
|
case HTTPVerb.options:
|
||||||
final request = prepareHttpRequest(
|
final request = prepareHttpRequest(
|
||||||
url: requestUrl,
|
url: requestUrl,
|
||||||
method: requestModel.method.name.toUpperCase(),
|
method: authenticatedRequestModel.method.name.toUpperCase(),
|
||||||
headers: headers,
|
headers: headers,
|
||||||
body: body,
|
body: body,
|
||||||
overrideContentType: overrideContentType,
|
overrideContentType: overrideContentType,
|
||||||
@@ -109,13 +116,13 @@ Future<(HttpResponse?, Duration?, String?)> sendHttpRequest(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (apiType == APIType.graphql) {
|
if (apiType == APIType.graphql) {
|
||||||
var requestBody = getGraphQLBody(requestModel);
|
var requestBody = getGraphQLBody(authenticatedRequestModel);
|
||||||
if (requestBody != null) {
|
if (requestBody != null) {
|
||||||
var contentLength = utf8.encode(requestBody).length;
|
var contentLength = utf8.encode(requestBody).length;
|
||||||
if (contentLength > 0) {
|
if (contentLength > 0) {
|
||||||
body = requestBody;
|
body = requestBody;
|
||||||
headers[HttpHeaders.contentLengthHeader] = contentLength.toString();
|
headers[HttpHeaders.contentLengthHeader] = contentLength.toString();
|
||||||
if (!requestModel.hasContentTypeHeader) {
|
if (!authenticatedRequestModel.hasContentTypeHeader) {
|
||||||
headers[HttpHeaders.contentTypeHeader] = ContentType.json.header;
|
headers[HttpHeaders.contentTypeHeader] = ContentType.json.header;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user