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

推荐订阅源

Y
Y Combinator Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
U
Unit 42
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog
GbyAI
GbyAI
Google DeepMind News
Google DeepMind News
博客园 - 【当耐特】
阮一峰的网络日志
阮一峰的网络日志
The Cloudflare Blog
N
Netflix TechBlog - Medium
P
Privacy International News Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
G
Google Developers Blog
Recorded Future
Recorded Future
The Hacker News
The Hacker News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
B
Blog RSS Feed
G
GRAHAM CLULEY
A
Arctic Wolf
N
News | PayPal Newsroom
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
The Register - Security
The Register - Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
V
Visual Studio Blog
Webroot Blog
Webroot Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 三生石上(FineUI控件)
aimingoo的专栏
aimingoo的专栏
P
Proofpoint News Feed
H
Heimdal Security Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Microsoft Azure Blog
Microsoft Azure Blog
小众软件
小众软件
M
MIT News - Artificial intelligence
V2EX - 技术
V2EX - 技术
Jina AI
Jina AI
TaoSecurity Blog
TaoSecurity Blog
NISL@THU
NISL@THU
云风的 BLOG
云风的 BLOG
爱范儿
爱范儿
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
WordPress大学
WordPress大学
V
V2EX
Cyberwarzone
Cyberwarzone
Stack Overflow Blog
Stack Overflow Blog
Cloudbric
Cloudbric
H
Hackread – Cybersecurity News, Data Breaches, AI and More

The Tracks of mulder21c

고정된 참조 위치 정보 선형 이미지의 최소 명도 대비 요구사항은 몇 대~ 몇? 단일 문자 단축키 (Character Key Shortcuts) 입력 방식(Input Modalities) 적응성(Adaptable) KWCAG 2.2 변경 사항 개요 Git hook으로 브랜치 이름 규칙 강제하기 댓글 시스템 remark42로 변경기 새 테마로 갈아입힘 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가지 질문
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가 필요해서 가져왔다

  • 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 테스트를 돌리려고 하면 토큰을 발급 받을 방법을 모르겠더라
결국 Swagger 사이트에 올리면 인증 테스트를 할 수 없더라는… 쿨럭…

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