mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 18:57:05 +08:00
JWT refactor
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
const kEmpty = '';
|
const kEmpty = '';
|
||||||
|
|
||||||
|
// API Key Auth
|
||||||
const kApiKeyHeaderName = 'x-api-key';
|
const kApiKeyHeaderName = 'x-api-key';
|
||||||
const kAddToLocations = [
|
const kAddToLocations = [
|
||||||
('header', 'Header'),
|
('header', 'Header'),
|
||||||
@@ -12,11 +14,14 @@ const kHintTextFieldName = "Header/Query Param Name";
|
|||||||
const kLabelApiKey = "API Key";
|
const kLabelApiKey = "API Key";
|
||||||
const kHintTextKey = "Key";
|
const kHintTextKey = "Key";
|
||||||
|
|
||||||
|
// Username-password auth
|
||||||
const kHintUsername = "Username";
|
const kHintUsername = "Username";
|
||||||
const kHintPassword = "Password";
|
const kHintPassword = "Password";
|
||||||
|
|
||||||
|
// Bearer Token AUth
|
||||||
const kHintToken = "Token";
|
const kHintToken = "Token";
|
||||||
|
|
||||||
|
// Digest Auth
|
||||||
const kInfoDigestUsername =
|
const kInfoDigestUsername =
|
||||||
"Your username for digest authentication. This will be sent to the server for credential verification.";
|
"Your username for digest authentication. This will be sent to the server for credential verification.";
|
||||||
const kInfoDigestPassword =
|
const kInfoDigestPassword =
|
||||||
@@ -35,3 +40,25 @@ const kInfoDigestQop =
|
|||||||
const kHintDataString = "Opaque";
|
const kHintDataString = "Opaque";
|
||||||
const kInfoDigestDataString =
|
const kInfoDigestDataString =
|
||||||
"Server-specified data string that should be returned unchanged in the authorization header. Usually obtained from server's 401 response.";
|
"Server-specified data string that should be returned unchanged in the authorization header. Usually obtained from server's 401 response.";
|
||||||
|
|
||||||
|
// JWT Auth
|
||||||
|
const kMsgAddToken = "Add JWT token to";
|
||||||
|
const kTooltipTokenAddTo = "Select where to add JWT token";
|
||||||
|
const kTextAlgo = "Algorithm";
|
||||||
|
const kTooltipJWTAlgo = "Select JWT algorithm";
|
||||||
|
const kStartAlgo = "HS";
|
||||||
|
const kHintSecret = "Secret Key";
|
||||||
|
const kInfoSecret =
|
||||||
|
"The secret key used to sign the JWT token. Keep this secure and match it with your server configuration.";
|
||||||
|
const kMsgSecret = "Secret is Base64 encoded";
|
||||||
|
const kMsgPrivateKey = "Private Key";
|
||||||
|
const kHintRSA = '''
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
Private Key in PKCS#8 PEM Format
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
''';
|
||||||
|
const kMsgPayload = "Payload (JSON format)";
|
||||||
|
const kHintJson =
|
||||||
|
'{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}';
|
||||||
|
const kHeaderPrefix = 'Bearer';
|
||||||
|
const kQueryParamKey = 'token';
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:apidash_core/apidash_core.dart';
|
import 'package:apidash_core/apidash_core.dart';
|
||||||
import 'package:apidash_design_system/apidash_design_system.dart';
|
import 'package:apidash_design_system/apidash_design_system.dart';
|
||||||
import 'package:apidash/widgets/widgets.dart';
|
import 'package:apidash/widgets/widgets.dart';
|
||||||
|
import 'consts.dart';
|
||||||
|
|
||||||
class JwtAuthFields extends StatefulWidget {
|
class JwtAuthFields extends StatefulWidget {
|
||||||
final AuthModel? authData;
|
final AuthModel? authData;
|
||||||
@@ -34,8 +35,8 @@ class _JwtAuthFieldsState extends State<JwtAuthFields> {
|
|||||||
_secretController = TextEditingController(text: jwt?.secret ?? '');
|
_secretController = TextEditingController(text: jwt?.secret ?? '');
|
||||||
_privateKeyController = TextEditingController(text: jwt?.privateKey ?? '');
|
_privateKeyController = TextEditingController(text: jwt?.privateKey ?? '');
|
||||||
_payloadController = TextEditingController(text: jwt?.payload ?? '');
|
_payloadController = TextEditingController(text: jwt?.payload ?? '');
|
||||||
_addTokenTo = jwt?.addTokenTo ?? 'header';
|
_addTokenTo = jwt?.addTokenTo ?? kAddToDefaultLocation;
|
||||||
_algorithm = jwt?.algorithm ?? 'HS256';
|
_algorithm = jwt?.algorithm ?? kJwtAlgos[0];
|
||||||
_isSecretBase64Encoded = jwt?.isSecretBase64Encoded ?? false;
|
_isSecretBase64Encoded = jwt?.isSecretBase64Encoded ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ class _JwtAuthFieldsState extends State<JwtAuthFields> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Add JWT token to",
|
kMsgAddToken,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@@ -53,13 +54,9 @@ class _JwtAuthFieldsState extends State<JwtAuthFields> {
|
|||||||
),
|
),
|
||||||
SizedBox(height: 4),
|
SizedBox(height: 4),
|
||||||
ADPopupMenu<String>(
|
ADPopupMenu<String>(
|
||||||
value:
|
value: kAddToLocationsMap[_addTokenTo],
|
||||||
_addTokenTo == 'header' ? 'Request Header' : 'Query Parameters',
|
values: kAddToLocations,
|
||||||
values: const [
|
tooltip: kTooltipTokenAddTo,
|
||||||
('header', 'Request Header'),
|
|
||||||
('query', 'Query Parameters'),
|
|
||||||
],
|
|
||||||
tooltip: "Select where to add JWT token",
|
|
||||||
isOutlined: true,
|
isOutlined: true,
|
||||||
onChanged: widget.readOnly
|
onChanged: widget.readOnly
|
||||||
? null
|
? null
|
||||||
@@ -74,7 +71,7 @@ class _JwtAuthFieldsState extends State<JwtAuthFields> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Text(
|
Text(
|
||||||
"Algorithm",
|
kTextAlgo,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@@ -83,23 +80,8 @@ class _JwtAuthFieldsState extends State<JwtAuthFields> {
|
|||||||
SizedBox(height: 4),
|
SizedBox(height: 4),
|
||||||
ADPopupMenu<String>(
|
ADPopupMenu<String>(
|
||||||
value: _algorithm,
|
value: _algorithm,
|
||||||
values: const [
|
values: kJwtAlgos.map((i) => (i, null)),
|
||||||
('HS256', 'HS256'),
|
tooltip: kTooltipJWTAlgo,
|
||||||
('HS384', 'HS384'),
|
|
||||||
('HS512', 'HS512'),
|
|
||||||
('RS256', 'RS256'),
|
|
||||||
('RS384', 'RS384'),
|
|
||||||
('RS512', 'RS512'),
|
|
||||||
('PS256', 'PS256'),
|
|
||||||
('PS384', 'PS384'),
|
|
||||||
('PS512', 'PS512'),
|
|
||||||
('ES256', 'ES256'),
|
|
||||||
('ES256K', 'ES256K'),
|
|
||||||
('ES384', 'ES384'),
|
|
||||||
('ES512', 'ES512'),
|
|
||||||
('EdDSA', 'EdDSA'),
|
|
||||||
],
|
|
||||||
tooltip: "Select JWT algorithm",
|
|
||||||
isOutlined: true,
|
isOutlined: true,
|
||||||
onChanged: widget.readOnly
|
onChanged: widget.readOnly
|
||||||
? null
|
? null
|
||||||
@@ -113,20 +95,19 @@ class _JwtAuthFieldsState extends State<JwtAuthFields> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
if (_algorithm.startsWith('HS')) ...[
|
if (_algorithm.startsWith(kStartAlgo)) ...[
|
||||||
AuthTextField(
|
AuthTextField(
|
||||||
readOnly: widget.readOnly,
|
readOnly: widget.readOnly,
|
||||||
controller: _secretController,
|
controller: _secretController,
|
||||||
isObscureText: true,
|
isObscureText: true,
|
||||||
hintText: "Secret key",
|
hintText: kHintSecret,
|
||||||
infoText:
|
infoText: kInfoSecret,
|
||||||
"The secret key used to sign the JWT token. Keep this secure and match it with your server configuration.",
|
|
||||||
onChanged: (value) => _updateJwtAuth(),
|
onChanged: (value) => _updateJwtAuth(),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
CheckboxListTile(
|
CheckboxListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
"Secret is Base64 encoded",
|
kMsgSecret,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@@ -145,7 +126,7 @@ class _JwtAuthFieldsState extends State<JwtAuthFields> {
|
|||||||
),
|
),
|
||||||
] else ...[
|
] else ...[
|
||||||
Text(
|
Text(
|
||||||
"Private Key",
|
kMsgPrivateKey,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@@ -163,11 +144,7 @@ class _JwtAuthFieldsState extends State<JwtAuthFields> {
|
|||||||
maxWidth: MediaQuery.sizeOf(context).width - 100,
|
maxWidth: MediaQuery.sizeOf(context).width - 100,
|
||||||
),
|
),
|
||||||
contentPadding: const EdgeInsets.all(18),
|
contentPadding: const EdgeInsets.all(18),
|
||||||
hintText: '''
|
hintText: kHintRSA,
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
Private Key in PKCS#8 PEM Format
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
||||||
''',
|
|
||||||
hintStyle: Theme.of(context).textTheme.bodyMedium,
|
hintStyle: Theme.of(context).textTheme.bodyMedium,
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
@@ -188,7 +165,7 @@ Private Key in PKCS#8 PEM Format
|
|||||||
],
|
],
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Text(
|
Text(
|
||||||
"Payload (JSON format)",
|
kMsgPayload,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@@ -206,8 +183,7 @@ Private Key in PKCS#8 PEM Format
|
|||||||
maxWidth: MediaQuery.sizeOf(context).width - 100,
|
maxWidth: MediaQuery.sizeOf(context).width - 100,
|
||||||
),
|
),
|
||||||
contentPadding: const EdgeInsets.all(18),
|
contentPadding: const EdgeInsets.all(18),
|
||||||
hintText:
|
hintText: kHintJson,
|
||||||
'{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}',
|
|
||||||
hintStyle: Theme.of(context).textTheme.bodyMedium,
|
hintStyle: Theme.of(context).textTheme.bodyMedium,
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
@@ -230,21 +206,26 @@ Private Key in PKCS#8 PEM Format
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _updateJwtAuth() {
|
void _updateJwtAuth() {
|
||||||
|
final jwt = AuthJwtModel(
|
||||||
|
secret: _secretController.text.trim(),
|
||||||
|
privateKey: _privateKeyController.text.trim(),
|
||||||
|
payload: _payloadController.text.trim(),
|
||||||
|
addTokenTo: _addTokenTo,
|
||||||
|
algorithm: _algorithm,
|
||||||
|
isSecretBase64Encoded: _isSecretBase64Encoded,
|
||||||
|
headerPrefix: kHeaderPrefix,
|
||||||
|
queryParamKey: kQueryParamKey,
|
||||||
|
header: '',
|
||||||
|
);
|
||||||
widget.updateAuth(
|
widget.updateAuth(
|
||||||
widget.authData?.copyWith(
|
widget.authData?.copyWith(
|
||||||
type: APIAuthType.jwt,
|
type: APIAuthType.jwt,
|
||||||
jwt: AuthJwtModel(
|
jwt: jwt,
|
||||||
secret: _secretController.text.trim(),
|
) ??
|
||||||
privateKey: _privateKeyController.text.trim(),
|
AuthModel(
|
||||||
payload: _payloadController.text.trim(),
|
type: APIAuthType.jwt,
|
||||||
addTokenTo: _addTokenTo,
|
jwt: jwt,
|
||||||
algorithm: _algorithm,
|
),
|
||||||
isSecretBase64Encoded: _isSecretBase64Encoded,
|
|
||||||
headerPrefix: 'Bearer',
|
|
||||||
queryParamKey: 'token',
|
|
||||||
header: '',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,23 @@ enum APIAuthType {
|
|||||||
const kDigestAlgos = ['MD5', 'MD5-sess', 'SHA-256', 'SHA-256-sess'];
|
const kDigestAlgos = ['MD5', 'MD5-sess', 'SHA-256', 'SHA-256-sess'];
|
||||||
const kQop = ['auth', 'auth-int'];
|
const kQop = ['auth', 'auth-int'];
|
||||||
|
|
||||||
|
const kJwtAlgos = [
|
||||||
|
'HS256',
|
||||||
|
'HS384',
|
||||||
|
'HS512',
|
||||||
|
'RS256',
|
||||||
|
'RS384',
|
||||||
|
'RS512',
|
||||||
|
'PS256',
|
||||||
|
'PS384',
|
||||||
|
'PS512',
|
||||||
|
'ES256',
|
||||||
|
'ES256K',
|
||||||
|
'ES384',
|
||||||
|
'ES512',
|
||||||
|
'EdDSA',
|
||||||
|
];
|
||||||
|
|
||||||
enum HTTPVerb {
|
enum HTTPVerb {
|
||||||
get("GET"),
|
get("GET"),
|
||||||
head("HEAD"),
|
head("HEAD"),
|
||||||
|
|||||||
Reference in New Issue
Block a user