Inflearn brand logo image

인프런 커뮤니티 질문&답변

프롬트님의 프로필 이미지
프롬트

작성한 질문수

차세대 Node.js 백엔드 서버 개발(Fastify & Prisma & Typescript와 함께하는)

swagger 설정

Swagger 문서 접근 권한

해결된 질문

작성

·

130

0

안녕하세요 Swagger UI의 경우 실제 서비스를 배포했을 때, 일반 유저는 /documentation에 접근하지 못 하도록 설정할 수 있나요? 내부 개발자들만 볼 수 있도록 접근 권한을 막는 방법이 있는지 궁금합니다.

 

감사합니다.

답변 1

0

Indie Coder님의 프로필 이미지
Indie Coder
지식공유자

swagger에 비밀번호를 적용하는 방법으로 basic-auth라는 것을 이용하는 방법이 있습니다.

설정에 관하여 간단하게 설명을 드리도록 하겠습니다.

우선 fastify/basic-auth를 다음과 같이 설치해 주시기 바랍니다.

참고로 강좌의 fastify버전의 경우 v4버전이기 때문에 basic-auth는 5버전을 사용하셔야 합니다.

 

npm i @fastify/basic-auth@5

 

다음으로 main.ts를 열고 필요한 설정을 해야 합니다 .

fastify에서 필요한 FastifyRequest, FastifyReply, HookHandlerDoneFunction을 불러오고

여기에 설치한 BasicAuth를 가져와 줍니다.

여기에 validate함수를 만들고 여기에서 아이디, 패스워드를 확인하도록 설정합니다

다음으로 register로 basicAuth를 등록하고 validate 함수를 연동해 줍니다.

이제 addHook에 onRequest를 설정하고

접근하는 url이 documentation일 경우 이 basic-auth가 작동하게 만들면 되겠습니다.

여기서 주의할 점으로 기존 예제와 달리 main.ts에서 register로 각종 플러그인을 등록할 경우 await을 사용해야 한다는 것입니다.

이부분을 유의해서 사용해 보시기 바랍니다.

 

main.ts

import Fastify from 'fastify'
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
import type { FastifyCookieOptions } from '@fastify/cookie'
import fasstifyCookie from '@fastify/cookie'
import routes from './routes'
import { SECRET_KEY } from './lib/constants'
import { currentlyAuthPlugin } from './plugin/authPlugin'
import { checkStartupUser, checkStartupArticle } from './startup'
import cors from '@fastify/cors'
import fastifySwagger from '@fastify/swagger'
import fastifySwaggerUi from '@fastify/swagger-ui'
import { swaggerConfig, swaggerUiConfig } from './config/swagger'

//추가코드
import { FastifyRequest, FastifyReply, HookHandlerDoneFunction } from 'fastify'
import BasicAuth from '@fastify/basic-auth';

const fastify = Fastify({
  logger: true,
  // https: {
  //   key: fs.readFileSync('./server.key'),
  //   cert: fs.readFileSync('./server.crt'),
  // }
}).withTypeProvider<TypeBoxTypeProvider>()

// fastify.get('/ping', async (request, reply) => {
//   return 'pong\n'
// })

// 각 register등록시 await 사용
await fastify.register(cors, {
  origin: true, // Access-Control-Allow-Origin
  credentials: true, //Access-Control-Allow-Credentials
})

await fastify.register(fastifySwagger, swaggerConfig)
await fastify.register(fastifySwaggerUi, swaggerUiConfig)

await fastify.register(fasstifyCookie, {
  secret: SECRET_KEY,
} as FastifyCookieOptions )

await fastify.register(currentlyAuthPlugin)
await fastify.register(routes)

// basic-auth with swagger 추가 코드
const authenticate = {realm: 'Westeros'}
await fastify.register(BasicAuth, {validate, authenticate})
function validate (username:string, password:string, req:FastifyRequest, reply:FastifyReply, done:HookHandlerDoneFunction) {
  if (username === 'admin' && password === '1111') {
    done()
  } else {
    done(new Error('Winter is coming'))
  }
}

fastify.addHook("onRequest", (req:FastifyRequest, res:FastifyReply, done:HookHandlerDoneFunction) => {
  if (req.url.startsWith(`/documentation`)) {
    fastify.basicAuth(req, res, done);
  } else {
    done();
  }    
}) 

const start = async () => {
  try {
    await checkStartupUser()
    await checkStartupArticle()    
    await fastify.listen({port: 8083})
    console.log(`Server Start!!`)
  }
  catch(error) {
    fastify.log.error(error)
    process.exit(1)    
  }
}

start()

 

 

 

 

프롬트님의 프로필 이미지
프롬트

작성한 질문수

질문하기