feat:限制必须api-key或登录2
parent
96d8404924
commit
cdf526bc25
|
|
@ -51,6 +51,12 @@ class AnonymousAuthenticationSerializer(serializers.Serializer):
|
||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_request_api_key(request):
|
||||||
|
if request is None:
|
||||||
|
return None
|
||||||
|
return request.query_params.get('api_key') or request.META.get('HTTP_X_APPLICATION_API_KEY')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def validate_application_api_key(application_id, api_key):
|
def validate_application_api_key(application_id, api_key):
|
||||||
if not api_key:
|
if not api_key:
|
||||||
|
|
@ -62,6 +68,7 @@ class AnonymousAuthenticationSerializer(serializers.Serializer):
|
||||||
).first()
|
).first()
|
||||||
if application_api_key is None:
|
if application_api_key is None:
|
||||||
raise AppUnauthorizedFailed(401, _("Authentication information is incorrect"))
|
raise AppUnauthorizedFailed(401, _("Authentication information is incorrect"))
|
||||||
|
return application_api_key
|
||||||
|
|
||||||
def auth(self, request, with_valid=True):
|
def auth(self, request, with_valid=True):
|
||||||
token = request.META.get('HTTP_AUTHORIZATION')
|
token = request.META.get('HTTP_AUTHORIZATION')
|
||||||
|
|
@ -83,10 +90,10 @@ class AnonymousAuthenticationSerializer(serializers.Serializer):
|
||||||
chat_user_type = ChatUserType.PLATFORM_USER.value
|
chat_user_type = ChatUserType.PLATFORM_USER.value
|
||||||
user_id = platform_user.id
|
user_id = platform_user.id
|
||||||
else:
|
else:
|
||||||
api_key = self.data.get('api_key') or request.META.get('HTTP_X_APPLICATION_API_KEY')
|
api_key = self.data.get('api_key') or self.get_request_api_key(request)
|
||||||
self.validate_application_api_key(application_access_token.application_id, api_key)
|
application_api_key = self.validate_application_api_key(application_access_token.application_id, api_key)
|
||||||
chat_user_id = token_details.get('chat_user_id') or str(uuid.uuid7())
|
chat_user_id = str(application_api_key.id)
|
||||||
chat_user_type = ChatUserType.ANONYMOUS_USER.value
|
chat_user_type = ChatUserType.APPLICATION_API_KEY.value
|
||||||
user_id = None
|
user_id = None
|
||||||
_type = AuthenticationType.CHAT_ANONYMOUS_USER
|
_type = AuthenticationType.CHAT_ANONYMOUS_USER
|
||||||
token = ChatUserToken(application_access_token.application_id, user_id, access_token, _type,
|
token = ChatUserToken(application_access_token.application_id, user_id, access_token, _type,
|
||||||
|
|
@ -110,7 +117,8 @@ class AuthProfileSerializer(serializers.Serializer):
|
||||||
raise NotFound404(404, _("Invalid access_token"))
|
raise NotFound404(404, _("Invalid access_token"))
|
||||||
application_id = application_access_token.application_id
|
application_id = application_access_token.application_id
|
||||||
if AnonymousAuthenticationSerializer.get_platform_user(request) is None:
|
if AnonymousAuthenticationSerializer.get_platform_user(request) is None:
|
||||||
AnonymousAuthenticationSerializer.validate_application_api_key(application_id, self.data.get("api_key"))
|
api_key = self.data.get("api_key") or AnonymousAuthenticationSerializer.get_request_api_key(request)
|
||||||
|
AnonymousAuthenticationSerializer.validate_application_api_key(application_id, api_key)
|
||||||
profile = {
|
profile = {
|
||||||
'authentication': False
|
'authentication': False
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
from django.db.models import QuerySet
|
from django.db.models import QuerySet
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from application.models import ApplicationAccessToken
|
from application.models import ApplicationAccessToken, ChatUserType
|
||||||
from common.auth.common import ChatUserToken
|
from common.auth.common import ChatUserToken
|
||||||
from common.auth.handle.auth_base_handle import AuthBaseHandle
|
from common.auth.handle.auth_base_handle import AuthBaseHandle
|
||||||
from common.constants.authentication_type import AuthenticationType
|
from common.constants.authentication_type import AuthenticationType
|
||||||
|
|
@ -42,7 +42,14 @@ class ChatAnonymousUserToken(AuthBaseHandle):
|
||||||
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect'))
|
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect'))
|
||||||
if not application_access_token.access_token == access_token:
|
if not application_access_token.access_token == access_token:
|
||||||
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect'))
|
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect'))
|
||||||
if application_access_token.authentication and ['PE', 'EE'].__contains__(edition):
|
if (
|
||||||
|
application_access_token.authentication and
|
||||||
|
['PE', 'EE'].__contains__(edition) and
|
||||||
|
chat_user_token.chat_user_type not in [
|
||||||
|
ChatUserType.PLATFORM_USER.value,
|
||||||
|
ChatUserType.APPLICATION_API_KEY.value
|
||||||
|
]
|
||||||
|
):
|
||||||
if chat_user_token.authentication.auth_type != application_access_token.authentication_value.get('type',
|
if chat_user_token.authentication.auth_type != application_access_token.authentication_value.get('type',
|
||||||
''):
|
''):
|
||||||
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect'))
|
raise AppAuthenticationFailed(1002, _('Authentication information is incorrect'))
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
{{ datetimeFormat(row.create_time) }}
|
{{ datetimeFormat(row.create_time) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('common.operation')" align="left" width="90">
|
<el-table-column :label="$t('common.operation')" align="left" width="130">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span class="mr-4">
|
<span class="mr-4">
|
||||||
<el-tooltip effect="dark" :content="$t('common.setting')" placement="top">
|
<el-tooltip effect="dark" :content="$t('common.setting')" placement="top">
|
||||||
|
|
@ -51,6 +51,11 @@
|
||||||
<AppIcon iconName="app-delete"></AppIcon>
|
<AppIcon iconName="app-delete"></AppIcon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
<el-tooltip effect="dark" :content="$t('common.copy')" placement="top">
|
||||||
|
<el-button type="primary" text @click="copyClick(getApiKeyAccessUrl(row))">
|
||||||
|
<AppIcon iconName="app-copy"></AppIcon>
|
||||||
|
</el-button>
|
||||||
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
@ -79,6 +84,10 @@ const apiType = computed(() => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
accessToken?: string
|
||||||
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits(['addData', 'refresh'])
|
const emit = defineEmits(['addData', 'refresh'])
|
||||||
|
|
||||||
const SettingAPIKeyDialogRef = ref()
|
const SettingAPIKeyDialogRef = ref()
|
||||||
|
|
@ -96,6 +105,10 @@ function settingApiKey(row: any) {
|
||||||
SettingAPIKeyDialogRef.value.open(row, 'APPLICATION')
|
SettingAPIKeyDialogRef.value.open(row, 'APPLICATION')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getApiKeyAccessUrl(row: any) {
|
||||||
|
return `${window.location.origin}${window.MaxKB.chatPrefix}/${props.accessToken}?api_key=${encodeURIComponent(row.secret_key)}`
|
||||||
|
}
|
||||||
|
|
||||||
function deleteApiKey(row: any) {
|
function deleteApiKey(row: any) {
|
||||||
MsgConfirm(
|
MsgConfirm(
|
||||||
`${t('views.applicationOverview.appInfo.APIKeyDialog.msgConfirm1')}: ${row.secret_key}?`,
|
`${t('views.applicationOverview.appInfo.APIKeyDialog.msgConfirm1')}: ${row.secret_key}?`,
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,6 @@ const { application } = useStore()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: Object,
|
data: Object,
|
||||||
apiInputParams: String,
|
apiInputParams: String,
|
||||||
apiKey: String,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['addData'])
|
const emit = defineEmits(['addData'])
|
||||||
|
|
@ -102,12 +101,10 @@ const source1 = ref('')
|
||||||
const source2 = ref('')
|
const source2 = ref('')
|
||||||
const source3 = ref('')
|
const source3 = ref('')
|
||||||
|
|
||||||
const apiKeyParam = computed(() => props.apiKey ? `api_key=${encodeURIComponent(props.apiKey)}` : '')
|
const urlParams1 = computed(() => (props.apiInputParams ? '?' + props.apiInputParams : ''))
|
||||||
const mergedParams = computed(() => [apiKeyParam.value, props.apiInputParams].filter(Boolean).join('&'))
|
const urlParams2 = computed(() => (props.apiInputParams ? '&' + props.apiInputParams : ''))
|
||||||
const urlParams1 = computed(() => (mergedParams.value ? '?' + mergedParams.value : ''))
|
|
||||||
const urlParams2 = computed(() => (mergedParams.value ? '&' + mergedParams.value : ''))
|
|
||||||
const urlParams3 = computed(() =>
|
const urlParams3 = computed(() =>
|
||||||
mergedParams.value ? '?mode=mobile&' + mergedParams.value : '?mode=mobile',
|
props.apiInputParams ? '?mode=mobile&' + props.apiInputParams : '?mode=mobile',
|
||||||
)
|
)
|
||||||
watch(dialogVisible, (bool) => {
|
watch(dialogVisible, (bool) => {
|
||||||
if (!bool) {
|
if (!bool) {
|
||||||
|
|
|
||||||
|
|
@ -184,9 +184,8 @@
|
||||||
ref="EmbedDialogRef"
|
ref="EmbedDialogRef"
|
||||||
:data="detail"
|
:data="detail"
|
||||||
:api-input-params="mapToUrlParams(apiInputParams)"
|
:api-input-params="mapToUrlParams(apiInputParams)"
|
||||||
:api-key="publicApiKey"
|
|
||||||
/>
|
/>
|
||||||
<APIKeyDialog ref="APIKeyDialogRef" @refresh="getPublicApiKey"/>
|
<APIKeyDialog ref="APIKeyDialogRef" :access-token="accessToken?.access_token"/>
|
||||||
|
|
||||||
<!-- 社区版访问限制 -->
|
<!-- 社区版访问限制 -->
|
||||||
<component :is="currentLimitDialog" ref="LimitDialogRef" @refresh="refresh"/>
|
<component :is="currentLimitDialog" ref="LimitDialogRef" @refresh="refresh"/>
|
||||||
|
|
@ -239,18 +238,13 @@ const APIKeyDialogRef = ref()
|
||||||
const EmbedDialogRef = ref()
|
const EmbedDialogRef = ref()
|
||||||
|
|
||||||
const accessToken = ref<any>({})
|
const accessToken = ref<any>({})
|
||||||
const publicApiKey = ref('')
|
|
||||||
const detail = ref<any>(null)
|
const detail = ref<any>(null)
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
const urlParams = computed(() => {
|
const urlParams = computed(() =>
|
||||||
const params = [
|
mapToUrlParams(apiInputParams.value) ? '?' + mapToUrlParams(apiInputParams.value) : '',
|
||||||
publicApiKey.value ? `api_key=${encodeURIComponent(publicApiKey.value)}` : '',
|
)
|
||||||
mapToUrlParams(apiInputParams.value),
|
|
||||||
].filter(Boolean)
|
|
||||||
return params.length ? '?' + params.join('&') : ''
|
|
||||||
})
|
|
||||||
const shareUrl = computed(
|
const shareUrl = computed(
|
||||||
() =>
|
() =>
|
||||||
`${window.location.origin}${window.MaxKB.chatPrefix}/` +
|
`${window.location.origin}${window.MaxKB.chatPrefix}/` +
|
||||||
|
|
@ -430,24 +424,6 @@ function openDialog() {
|
||||||
EmbedDialogRef.value.open(accessToken.value?.access_token)
|
EmbedDialogRef.value.open(accessToken.value?.access_token)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPublicApiKey() {
|
|
||||||
publicApiKey.value = ''
|
|
||||||
loadSharedApi({type: 'applicationKey', systemType: apiType.value})
|
|
||||||
.getAPIKey(id as string, loading)
|
|
||||||
.then((res: any) => {
|
|
||||||
const key = res.data?.find((item: any) => item.is_active) || res.data?.[0]
|
|
||||||
if (key) {
|
|
||||||
publicApiKey.value = key.secret_key
|
|
||||||
return
|
|
||||||
}
|
|
||||||
loadSharedApi({type: 'applicationKey', systemType: apiType.value})
|
|
||||||
.postAPIKey(id as string, loading)
|
|
||||||
.then((apiKeyRes: any) => {
|
|
||||||
publicApiKey.value = apiKeyRes.data?.secret_key || ''
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAccessToken() {
|
function getAccessToken() {
|
||||||
loadSharedApi({type: 'application', systemType: apiType.value})
|
loadSharedApi({type: 'application', systemType: apiType.value})
|
||||||
.getAccessToken(id, loading)
|
.getAccessToken(id, loading)
|
||||||
|
|
@ -492,7 +468,6 @@ function refresh() {
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getDetail()
|
getDetail()
|
||||||
getAccessToken()
|
getAccessToken()
|
||||||
getPublicApiKey()
|
|
||||||
changeDayHandle(history_day.value)
|
changeDayHandle(history_day.value)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue