2024/11/19

Auto-filling JWT Token in NestJS Swagger Documentation


import {
    DocumentBuilder,
    SwaggerModule as NestSwaggerModule
} from '@nestjs/swagger'

     // 建立Swagger的設定
        const config = new DocumentBuilder()
            .addSecurity('JWT', {
                type: 'http',
                scheme: 'bearer',
                bearerFormat: 'JWT',
                in: 'header'
            })
            .build()

        // 設定Swagger的路徑
        NestSwaggerModule.setup(path, app, document, {
            swaggerOptions: {
                // 永久儲存授權
                persistAuthorization: true,
                // 預設分類不展開
                docExpansion: 'none',
                onComplete: () => {
                    // 設定是否為登入請求
                    let isLoginRequest = false

                    // 取得fetch
                    const originalFetch = window.fetch

                    // 覆寫fetch
                    window.fetch = async function (...args) {
                        // 執行原本的fetch
                        const response = await originalFetch.apply(this, args)

                        try {
                            // 如果為SingIn Request
                            if (isLoginRequest) {
                                // clone response
                                const clone = response.clone()
                                // 取得Content-Type
                                const contentType =
                                    response.headers.get('content-type')

                                // 如果為JSON
                                if (contentType?.includes('application/json')) {
                                    // 取得JSON
                                    const data = await clone.json()

                                    // 檢查 token
                                    const token = data?.data?.token
                                    // 如果有token
                                    if (token) {
                                        // 設定 Token
                                        ;(window as any).ui.preauthorizeApiKey(
                                            'JWT',
                                            token
                                        )

                                        // 重置標記
                                        isLoginRequest = false
                                    }
                                }
                            }
                        } catch (error) {
                            console.error('Error processing response:', error)
                        }

                        return response
                    }

                    // 添加點擊事件監聽
                    ;(window as any).document.addEventListener(
                        'click',
                        (e: any) => {
                            if (
                                e.target.matches(
                                    '.btn.execute.opblock-control__btn'
                                )
                            ) {
                                // 取得URL的Query
                                const urlQuery = window.location.hash.slice(1)
                                // 如果URL的Query包含 _singIn_
                                if (urlQuery.includes('_singIn_')) {
                                    // 如果是登入請求
                                    isLoginRequest = true
                                }
                            }
                        }
                    )
                }
            },
            customSiteTitle: 'API Documentation'
        })