惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
Spread Privacy
Spread Privacy
S
Securelist
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Project Zero
Project Zero
G
GRAHAM CLULEY
Stack Overflow Blog
Stack Overflow Blog
爱范儿
爱范儿
Scott Helme
Scott Helme
S
Security Affairs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
The Exploit Database - CXSecurity.com
The Hacker News
The Hacker News
雷峰网
雷峰网
N
News and Events Feed by Topic
宝玉的分享
宝玉的分享
O
OpenAI News
小众软件
小众软件
C
Cybersecurity and Infrastructure Security Agency CISA
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Visual Studio Blog
I
Intezer
Martin Fowler
Martin Fowler
S
Security @ Cisco Blogs
A
Arctic Wolf
Engineering at Meta
Engineering at Meta
U
Unit 42
L
Lohrmann on Cybersecurity
Google Online Security Blog
Google Online Security Blog
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
WordPress大学
WordPress大学
M
MIT News - Artificial intelligence
Schneier on Security
Schneier on Security
V2EX - 技术
V2EX - 技术
IT之家
IT之家
The Register - Security
The Register - Security
T
Tailwind CSS Blog
GbyAI
GbyAI
量子位
人人都是产品经理
人人都是产品经理
Recorded Future
Recorded Future
W
WeLiveSecurity
AWS News Blog
AWS News Blog
B
Blog RSS Feed
腾讯CDC
Hacker News - Newest:
Hacker News - Newest: "LLM"
Microsoft Security Blog
Microsoft Security Blog

The Tracks of mulder21c

Atomic Design + Storybook 적용 후기 개발환경 WSL2 + zsh로 갈아타기 pass function as props in vue 2020년 회고 colum flexbox에서 padding bottom 문제 해결 Nuxt를 통해 보는 프론트엔드 개발자가 하는 일 Nuxt Router kebab-case 처리 JS to SCSS 변환 Nuxt + Storybook 통합 하기 2020 이직 이야기 2020 이직 이야기 2020 이직 이야기 2020 이직 이야기 Windows에서 PM2 실행 오류 해결 오픈톡 정지에 대한 카카오톡 고객센터 후기 배려에 대한 단상 학습이 잘 되지 않는 이유 웹팩 4 마이그레이션 삽질기 babel 7 업데이트 후 node_modules 패키지가 변환되지 않는다면? white space는 4px이다? 정말? 2020년 시간 관리를 위해서 도입 한 툴들 Codility Lesson 5 — PassingCars 2019년 회고 Codility Lesson 4 — MissingInteger Codility Lesson 4 — MaxCounters Codility Lesson 4 — FrogRiverOne Codility Lesson — PermCheck 착각은 자유가 아닌각 세미나 진행 후기 Codility Lesson 3 — tapeEquilibrium Codility Lesson 3 — PermMissingElm Codility Lesson 3 — FrogJump 알고리즘 연습을 다시 시작했다. Codility Lesson 2 — CyclicRotation Codility Lesson 2 — OddOccurrencesInArray Codility Lesson 1 — BinaryGap 아이패드 구매 하고 3주 써 본 기록 세미나 어떻게 준비해야 할까? HTML은 웹이다 접근성 향상을 위한 이름 짓기 접근성 교육에서 자주 나오는 상위 5가지 질문 접근 가능한 숨김 텍스트 깃북 파일 저장 시 오류 문제 해결 크로스 브라우징이란? 블로그 테마 만들기 시작 2018년 회고 학습에 대한 오해 모르는 사람에게 질문할거면 예의 좀 지켜라 파이썬으로 웹 크롤러 만들기 해쉬 링크 오프셋 조정하기
json-server에 사용자 인증 구현하기
멀더끙 · 2021-02-06 · via The Tracks of mulder21c

최근 진행했던 한 기업의 사전 과제에서 JWT 인증 처리를 포함한 Mock API 구현이 범위에 있어 시도해 봤던 방법을 기록으로 남겨본다. (JSON server는 사용할 줄 안다는 가정하에서 포스팅한다.)

내 경우엔 mock API 구현에 편의를 위해 JSON server를 사용해 왔는데, 역시 이를 베이스로 하고 JWT 관련 패키지를 추가하여 구현을 시도해봤다.

추가 한 auth 관련 패키지

  • json-server-auth

    JSON server용으로 만들어진 JWT 인증 미들웨어다.
    다른 몇 가지 패키지들을 찾아보고 가장 간편하게 구축 가능하고 문서화가 잘 되어 있는 녀석을 찾다보니 이 녀석으로 정착했다.

  • jsonwebtoken

    패키지 이름 그대로 JWT의 구현체인데, JWT verifier가 필요해서 가져왔다 = _=a

  • cors

    CORS 관련 설정을 위한 Express용 미들웨어로, HEADER를 조작하게 되면 pre-flight 요청을 처리해야 하는데 여기서 CORS 문제가 발생되기 때문에 이를 해결하기 위해서 설치 했다.

기본 설정

사실 json-server-auth가 웬만한 것들은 알아서 처리해주고 있기 때문에 특별히 할 것은 없다.

해당 매뉴얼을 참고해서 미리 정의 된 API 이름을 그대로 가져다 쓰기만 하면 JWT 발급부터 오류까지 알아서 처리해 준다. (참고로 이 토큰의 유효시간은 1시간이다)

따라서, 해야 할 일이라고는 미리 정의 된 API 외 다른 이름을 쓰고 싶을 경우의 router rewrite, CORS 설정 정도면 충분하다.

설정 방법은 express 공식문서를 참고했다.

const server = jsonServer.create();
const auth = require("json-server-auth");
const cors = require("cors");

/**
 * 과제에선 GET, POST, DELETE만 필요했기 때문에
 * 3가지 method만 작성했고,
 * 어차피 mock api이고 local에서 구동되는 거라
 * origin을 all(*)로 설정했다.
 */
server.use(
  cors({
    origin: "*",
    preflightContinue: false,
    methods: "GET,POST,DELETE"
  })
);
/**
 * 모든 router에 대해 preflight 요청 활성화
 */
server.options("*", cors());

// 중략

server.use(auth);

단지 이 기본 설정만으로 회원 가입, 로그인 시 JWT 발급이 가능하고 이후 클라이언트에서 API 호출 시 Authorization Header에 Bearer Token을 담아 던지기만 하면 된다.

users/me 구현

그런데, json-server-auth는 회원 가입 혹은 로그인 시 accessToken만을 응답으로 내려주기 때문에 사용자를 식별할 방법이 없다.

아쉽게도 이 부분은 직접 구현을 해야 하는 부분으로 보였다.
역시 대부분 생각하는게 비슷한지 동일한 니즈를 가진 유저의 질문이 issue로 등록되어 있었고 해당 issue를 참고해서 별도로 구현했다.

/**
 * JWT 검증을 위해 jsonwebtoken 모듈을 가져왔고,
 * JWT의 비밀키는 json-server-auth에서 가지고 있다
 */
const jwt = require("jsonwebtoken");
const JWT_SECRET_KEY = require("json-server-auth/dist/constants").JWT_SECRET_KEY;

// 중략

server.get(`/users/me`, auth, (req, res) => {
  const { authorization } = req.headers;
  if (!authorization) {
    res.status(401).jsonp("Missing authorization header");
    return;
  }
  const [scheme, token] = authorization.split(" ");
  if (scheme !== "Bearer") {
    res.status(401).jsonp("Incorrect authorization scheme");
    return;
  }
  if (!token) {
    res.status(401).jsonp("Missing token");
    return;
  }

  try {
    const data = jwt.verify(token, JWT_SECRET_KEY);
    const { db } = req.app;
    // ... 은 그냥 나머지 property들
    const { id, email, ... } = db
      .get("users")
      .find({ email: data.email })
      .value();
    res.status(200).json({ id, email, ... });
  } catch (err) {
    res.status(401).jsonp(err.message);
  }
});

이렇게 해서 사용자 정보를 내려주는 users/me API도 구현했다.

생각보다 어렵지 않게 mock에서도 인증 구현이 되서 이후로도 요긴하게(?) 사용할 수 있을 것 같다.

아쉬운 부분

json-server-auth가 내부적으로 정확히 어떻게 동작하는지까지는 찾아보지 않았는데, mock api 구동 중에 post 등으로 발생된 리소스는 권한이 정상적으로 동작하는 반면, mock api가 구동 되기 전에 존재하는 리소스는 권한이 정상적으로 동작하지 않았다.

즉, 생성한 유저만 조회가 가능한 리소스를 설정해두었을 때, 테스트 중 mock api를 내렸다가 다시 올리면 기존 리소스가 사라지는 것은 아니기 때문에 기존 것이 전체가 조회 가능한 권한이 되어버리는 문제가 발생하기는 하더라...

그리고 또 한가지, mock API 작성과 동시에 swagger 문서를 만들었는데 swagger 사이트에 올려 API 테스트를 돌리려고 하면 토큰을 발급 받을 방법을 모르겠더라 = _=a
결국 Swagger 사이트에 올리면 인증 테스트를 할 수 없더라는... 쿨럭...

물론 로컬에 swagger도 설치해서 구동하면 되기는 하지만, 협업 시에는 response에 관련 된 yml만 작성해 올리는 걸로 만족해야 하나 싶다.