๐Ÿ“ ํŽ˜์ด์ง€ ์ด๋™ ์•ˆ๋‚ด

์ด ํฌ์ŠคํŠธ๋Š” ์ƒˆ๋กœ์šด ๋ธ”๋กœ๊ทธ๋กœ ์ด์ „๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

2์ดˆ ํ›„ ์ž๋™์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค...

๐Ÿ‘‰ ์ง€๊ธˆ ๋ฐ”๋กœ ์ด๋™ํ•˜๊ธฐ
Skip to main content

Rust๋กœ ๋งŒ๋“  node.js์šฉ jsonwebtoken ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

ยท 5 min read
yoonhoGo
Rust ์žฌ๋ฐŒ๋‹ค!

์ •ํ™•ํžˆ ๊ธฐ์–ต์€ ์•ˆ๋‚˜์ง€๋งŒ Mozilla Servo๊ฐ€ ๋ฆด๋ฆฌ์ฆˆ ๋˜์—ˆ์œผ๋‹ˆ ์•„๋งˆ๋„ 2016์ด ๋งž์„๊ฑฐ ๊ฐ™๋‹ค. ๊ทธ๋•Œ๋Š” ํ•œ์ฐฝ ๋Œ€ํ•œ๋ฏผ๊ตญ์˜ ์ž๋ž‘์Šค๋Ÿฌ์šด ๊ณต๊ตฐ ๋ณ‘์žฅ์œผ๋กœ์„œ ๋‹น๋‹นํžˆ ์ „๋‚  ์•ผ๊ฐ„ ๊ทผ๋ฌด๋ฅผ ๋งˆ์น˜๊ณ  ์ทจ์นจ ํ›„ ์‚ฌ์ง€๋ฐฉ์— ์žˆ์—ˆ์„ ๋•Œ์˜€๋‹ค(ํ˜น์€ ์ฃผ๋ง์ด์–ด์„œ ๋น„๋ฒˆ์ด์—ˆ๊ฑด?). ๊ณ„๊ธฐ๋Š” ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ์–ด๋–ค ์ด์œ ๋กœ Mozilla์—์„œ Servo๋ผ๋Š” ์›น ๋ธŒ๋ผ์šฐ์ € ์—”์ง„์„ ์ƒˆ๋กœ ๊ฐœ๋ฐœํ•˜์˜€๊ณ  ์ด๋Š” Rust๋ผ๋Š” Mozilla์—์„œ ๋งŒ๋“  ์ƒˆ๋กœ์šด ์–ธ์–ด๋กœ ๊ฐœ๋ฐœ ๋๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ๋˜์—ˆ๋‹ค. ์–ด์งธ์„œ์˜€์„๊นŒ? ์ด๊ฑด ๋งˆ์น˜ ์šด๋ช…๊ฐ™์€ ๋งŒ๋‚จ์ด์—ˆ์„๊นŒ? ๋‚˜๋Š” Rust ์ปจ์…‰์„ ๋ณด๊ณ ๋Š” ๊ทธ๋Œ€๋กœ ์ด ์–ธ์–ด์— ๋งค๋ฃŒ๋˜์—ˆ๋‹ค.

๊ทธ ๋’ค๋กœ Rust ์–ธ์–ด์— ๋Œ€ํ•ด์„œ ํŠœํ† ๋ฆฌ์–ผ๊ณผ ๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด์„œ ํ•™์Šต์€ ํ–ˆ์ง€๋งŒ ์šฐ๋ฆฌ๋‚˜๋ผ์—์„œ ํ• ๋งŒํ•œ ํ”„๋กœ์ ํŠธ๋„ ์—†์—ˆ๊ณ  ๊ทธ ์ดํ›„๋กœ Node.js๋ฅผ ์ ‘ํ•˜๋ฉด์„œ ์ด์ชฝ์œผ๋กœ ๊ฐœ๋ฐœ๋งŒ ์ง„ํ–‰ํ•˜๋‹ค ๋ณด๋‹ˆ Rust๋Š” ๋‚ด ๋งˆ์Œ ์† ํ•œ์ผ ์— ์žˆ๋Š” ์ง์‚ฌ๋ž‘ ๊ฐ™์€ ์กด์žฌ์˜€๋‹ฌ๊นŒ?

๊ทธ๋ ‡๊ฒŒ ์˜ค๋žœ ์‹œ๊ฐ„์ด ์ง€๋‚˜๊ณ  ์ตœ๊ทผ Rust๋กœ ๊ฐœ๋ฐœ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ์—ฌ๋Ÿฟ ์†Œ๊ฐœ ๋˜๋ฉด์„œ ๋‚˜๋„ ๋‹ค์‹œ Rust๋กœ ๊ฐœ๋ฐœ ํ•ด๋ณด๊ณ  ๋งˆ์Œ์ด ์†Ÿ๊ตฌ์ณค๋‹ค.

๊ทธ๋ž˜์„œ ์ด๋ฒˆ์— ์„ค์—ฐํœด๋ฅผ ๋งž์•„ ๊ฐ„๋‹จํ•œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ข€ ์ง„ํ–‰ํ•ด๋ณด๋ฉด ์ข‹๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์— โ€œneonโ€์„ ์ด์šฉํ•ด์„œ rust์—์„œ ์‚ฌ์šฉํ•˜๋Š” jsonwebtoken์„ โ€œnode-jsonwebtokenโ€ API ํ˜ธํ™˜์„ ๋งž์ถฐ node.js์šฉ์œผ๋กœ ๋งŒ๋“ค์–ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค.

...

๊ทธ๋ฆฌ๊ณ  ๋งŒ๋“ค์—ˆ๋‹ค! ๋‘-๋‘ฅ!

neon-jsonwebtokenโ€‹

Installโ€‹

ํ›„๊ธฐ์— ๋‚˜์˜ค๊ฒ ์ง€๋งŒ ์•„์ฃผ ์ž‘์€ ์‹ค์ˆ˜๋กœ ๋ฐฐํฌ๊ฐ€ ์•ˆ๋ผ์„œ 3์ผ์— ๋ฐฐํฌํ•  ์˜ˆ์ •์ด๋‹ค.

$npm i neon-jsonwebtoken

Featureโ€‹

  • Sign jsonwebtoken
  • Decode jsonwebtoken
  • Verify Jsonwebtoken

Dependencies and Environments Supportโ€‹

  • Neon
  • Node.js version 12 and higher LTS
  • Rust stable 1.18 and higher

Usageโ€‹

์•„์ง Document๋ฅผ ๋งŒ๋“ค ์‹œ๊ฐ„์ด ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์•˜๋‹ค. ๊ทธ๋ ‡์ง€๋งŒ node-jsonwebtoken ๊ณผ ๋™์ผํ•œ API๋ฅผ ์œ ์ง€ํ•˜๋ ค๊ณ  ํ–ˆ๋‹ค. ๊ตฌํ˜„๋˜์ง€ ์•Š์€ ๋ถ€๋ถ„๋งŒ ํ™•์ธํ•œ๋‹ค๋ฉด ์‚ฌ์šฉํ•˜๋Š”๋ฐ๋Š” ์–ด๋ ต์ง€ ์•Š์„ ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ•œ๋‹ค. ๋ฌธ์„œ๋Š” ์กฐ๋งŒ๊ฐ„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํ•˜๊ฒ ๋‹ค.

import * as jwt from 'neon-jsonwebtoken';

const token = jwt.sign(payload, key, signOptions);
const decodedPaylaod = jwt.decode(token, decodeOptions);
const paylaod = jwt.verify(token, key, verifyOptions);

To-Doโ€‹

  • Asynchronous
  • mutatePayload option in sign function
  • clockTolerance, maxAge, clockTimestamp, nonce options in veirfy function
  • Synchronize Error messages with node-jsonwebtoken

Benchmarkโ€‹

๊ฐ€์žฅ ์ธ์ƒ์ ์ธ ๋ถ€๋ถ„์€ Rust ์ƒํƒœ๊ณ„๋ฅผ ์ด์šฉํ•˜์—ฌ neon์œผ๋กœ node.js์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํฌํŒ… ํ–ˆ์„ ๋ฟ์ธ๋ฐ ์ผ๋ฐ˜ ๋…ธ๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋น„ํ•ด ์„ฑ๋Šฅ์—์„œ ๋” ์•ž์„œ๋Š” ์ˆ˜์น˜๊ฐ€ ๋‚˜์™”๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

ํ…Œ์ŠคํŠธ๋Š” ๊ฐ ํŒŒ์ผ๋งˆ๋‹ค 5๋งŒ๋ฒˆ์˜ iterator๋ฅผ ๊ฐ€์ง€๊ณ  ์ง„ํ–‰ํ•˜์˜€๊ณ  ํ…Œ์ŠคํŠธ๋งˆ๋‹ค 10ํšŒ ์”ฉ ๋ฐ˜๋ณตํ•˜์—ฌ ํ‘œ์ค€ ์‹œ๊ฐ„๊ณผ ์ตœ์žฅ, ์ตœ๋‹จ ์‹œ๊ฐ„์„ ๊ตฌํ•˜์˜€๋‹ค.

ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” hyperfine์„ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

Sign tokenโ€‹

node-jsonwebtoken์€ jws์— ์˜์กด์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ  callback์„ ์ œ๊ณตํ•œ๋‹ค๋ฉด event stream์œผ๋กœ ๋น„๋™๊ธฐ ์‘๋‹ต์„ ์ œ๊ณตํ•œ๋‹ค.

neon-jsonwebtoken์€ ์•„์ง ๋น„๋™๊ธฐ ์‘๋‹ต์„ ๋งŒ๋“ค์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ new Promise ๋กœ ๋ž˜ํ•‘ํ•ด์„œ ํ…Œ์ŠคํŠธ ํ•ด๋ณด์•˜๋Š”๋ฐ ๋™๊ธฐ์ฝ”๋“œ๋ฅผ Promise๋กœ ์ŒŒ์„ ๋ฟ์ธ๋ฐ ํ•ญ์ƒ ๋” ๋น ๋ฅธ ์„ฑ๋Šฅ์ด ๋‚˜์˜จ ์ ์—์„œ ์ดํ•ดํ•  ์ˆ˜ ์—†์—ˆ๋‹ค. ์ด์— ๋Œ€ํ•˜์—ฌ ์ž๋ฃŒ๊ฐ€ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜ ์ œ๊ณตํ•œ ๋ฐ์ดํ„ฐ์—์„œ๋Š” ํ‘œ๊ธฐํ•˜์ง€ ์•Š์•˜๋‹ค.

โฏ hyperfine "node ./node-jsonwebtoken.js" "node ./node-jsonwebtoken-async.js" "node ./neon-jsonwebtoken.js"
Benchmark 1: node ./node-jsonwebtoken.js
Time (mean ยฑ ฯƒ): 1.069 s ยฑ 0.042 s [User: 1.106 s, System: 0.074 s]
Range (min โ€ฆ max): 1.019 s โ€ฆ 1.135 s 10 runs

Benchmark 2: node ./node-jsonwebtoken-async.js
Time (mean ยฑ ฯƒ): 1.405 s ยฑ 0.032 s [User: 1.892 s, System: 0.203 s]
Range (min โ€ฆ max): 1.367 s โ€ฆ 1.476 s 10 runs

Benchmark 3: node ./neon-jsonwebtoken.js
Time (mean ยฑ ฯƒ): 661.7 ms ยฑ 22.4 ms [User: 629.1 ms, System: 52.1 ms]
Range (min โ€ฆ max): 644.0 ms โ€ฆ 705.9 ms 10 runs

Summary
'node ./neon-jsonwebtoken.js' ran
1.62 ยฑ 0.08 times faster than 'node ./node-jsonwebtoken.js'
2.12 ยฑ 0.09 times faster than 'node ./node-jsonwebtoken-async.js'

Decode tokenโ€‹

decode์—์„œ๋Š” ํŠน์ดํ•˜๊ฒŒ๋„ node-jsonwebtoken์ด ๋” ์ข‹์€ ์„ฑ๋Šฅ์„ ๋ณด์—ฌ์คฌ๋‹ค. ์—ฌ๋Ÿฌ ์ด์œ ๋ฅผ ์ƒ๊ฐํ•ด๋ดค์ง€๋งŒ ์ด๊ฑฐ๋‹ค ํ•˜๋Š” ์ด์œ ๋Š” ์ฐพ์ง€ ๋ชปํ–ˆ๋‹ค. ์ง์ž‘๊ฐ€๋Š”๊ฒŒ ์žˆ๋‹ค๋ฉด ์ œ๋ณดํ•ด์ฃผ์‹œ๋ฉด ์ข‹๊ฒ ๋‹ค.

โฏ hyperfine "node ./node-jsonwebtoken-decode.js" "node ./neon-jsonwebtoken-decode.js"                      
Benchmark 1: node ./node-jsonwebtoken-decode.js
Time (mean ยฑ ฯƒ): 1.464 s ยฑ 0.045 s [User: 1.520 s, System: 0.088 s]
Range (min โ€ฆ max): 1.414 s โ€ฆ 1.556 s 10 runs

Benchmark 2: node ./neon-jsonwebtoken-decode.js
Time (mean ยฑ ฯƒ): 1.630 s ยฑ 0.041 s [User: 1.701 s, System: 0.088 s]
Range (min โ€ฆ max): 1.584 s โ€ฆ 1.698 s 10 runs

Summary
'node ./node-jsonwebtoken-decode.js' ran
1.11 ยฑ 0.04 times faster than 'node ./neon-jsonwebtoken-decode.js'

Verify tokenโ€‹

ํ† ํฐ ๊ฒ€์ฆ์—์„œ๋Š” ์˜คํžˆ๋ ค ๋” ์ข‹์€ ์„ฑ๋Šฅ์ด ๋‚˜ํƒ€๋‚ฌ๋‹ค. ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” HMAC ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•ด์„œ๋งŒ ํ‘œ๊ธฐํ–ˆ๋Š”๋ฐ ์ฐจํ›„ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ณ„๋กœ ๋ฒค์น˜๋งˆํฌ ์„ฑ๋Šฅ์„ ํ‘œ๊ธฐํ•ด์•ผ๊ฒ ๋‹ค.

์ฐธ๊ณ ๋กœ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ๋Š” ๋™์ผํ•˜๊ฒŒ node-jsonwebtoken์ด ํ† ํฐ์„ ๋ฐœํ–‰ํ•œ ๋กœ์ง์ด ํฌํ•จ ๋˜์–ด์žˆ์œผ๋ฏ€๋กœ sign token์—์„œ node-jsonwebtoken์ด ๊ฑธ๋ฆฐ ์‹œ๊ฐ„๋งŒํผ ๋นผ์ค˜์•ผ ์‹ค์งˆ์ ์ธ ์‹œ๊ฐ„์ด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

โฏ hyperfine "node ./node-jsonwebtoken-verify.js" "node ./neon-jsonwebtoken-verify.js"
Benchmark 1: node ./node-jsonwebtoken-verify.js
Time (mean ยฑ ฯƒ): 2.104 s ยฑ 0.080 s [User: 2.129 s, System: 0.111 s]
Range (min โ€ฆ max): 2.003 s โ€ฆ 2.295 s 10 runs

Benchmark 2: node ./neon-jsonwebtoken-verify.js
Time (mean ยฑ ฯƒ): 1.864 s ยฑ 0.118 s [User: 1.875 s, System: 0.104 s]
Range (min โ€ฆ max): 1.751 s โ€ฆ 2.120 s 10 runs

Summary
'node ./neon-jsonwebtoken-verify.js' ran
1.13 ยฑ 0.08 times faster than 'node ./node-jsonwebtoken-verify.js'

ํ›„๊ธฐโ€‹

์•ฝ ์ดํ‹€์— ๊ฑธ์ณ์„œ ์ž‘์„ฑํ–ˆ๋Š”๋ฐ Rust์—์„œ ์‚ฌ์šฉ๋˜๋Š” jsonwebtoken๊ณผ serde serializer, neon์— ๋Œ€ํ•ด์„œ ํŒŒ์•…ํ•˜๋Š”๋ฐ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ ธ๋‹ค.

ํ‰์†Œ์—๋Š” ํšŒ์‚ฌ ์ผ๋กœ ๋ฐ”์˜๋‹ˆ ์„ค ์—ฐํœด ์ค‘์— ๋งˆ๋ฌด๋ฆฌ ์ง€์œผ๋ ค๊ณ  ์ฝ”๋“œ๋ฅผ ์งœ๋‹ค๋ณด๋‹ˆ ์ •๋ฆฌ๊ฐ€ ์•ˆ๋œ ๋ถ€๋ถ„๋„ ๋งŽ์ด ์žˆ๋‹ค. ์•„์ง ๋Ÿฌ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ์ฝ”๋“œ ์•„ํ‚คํ…์ณ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฐ€์ ธ๊ฐ€๋Š”์ง€๋„ ํ™•์‹คํ•˜๊ฒŒ ๋ชจ๋ฅด๊ฒ ๊ณ  ์ฝ”๋“œ๋Š” ์ฐจ์ฐจ ๋ฆฌํŒฉํ† ๋ง ํ•ด๋ณด๋Š” ๊ฒƒ์œผ๋กœ!

neon์ด ์ƒ๊ฐ๋ณด๋‹ค ํ™ˆํŽ˜์ด์ง€๊ฐ€ ๋ถ€์‹คํ•œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค. ํ™ˆํŽ˜์ด์ง€์—์„œ๋Š” ์ดˆ๊ธฐ ์‚ฌ์šฉ๋ฒ• ์ •๋„๋งŒ ์ฐธ๊ณ ํ•˜๊ณ  ๋‚˜๋จธ์ง€๋Š” crate api ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜๋Š” ํŽธ์ด ์ข‹๋‹ค.

npm publish๋ฅผ ์ƒ๊ฐ์—†์ด ํ–ˆ๋‹ค๊ฐ€ rust src๊นŒ์ง€ ๊ฐ™์ด ์˜ฌ๋ผ๊ฐ€์„œ ์ทจ์†Œํ•˜๊ณ ...
์ƒ๊ฐ์—†์ด .npmignore์— src๋งŒ ์ถ”๊ฐ€ํ•ด์„œ publish ํ–ˆ๋‹ค๊ฐ€ cargo target ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ๋”ธ๋ ค๊ฐ€์„œ ๊ฐ•์ œ ์ทจ์†Œํ–ˆ๋”๋‹ˆ ์ด๋ฏธ ๋ฐฐํฌ๊ฐ€ ๋˜์–ด๋ฒ„๋ ธ๊ณ ...
์ƒ๊ฐ์—†์ด npm unpublish๋ฅผ ํ–ˆ๋‹ค๊ฐ€ ํ•˜๋ฃจ๊ฐ„ ๋ฐฐํฌํ•  ์ˆ˜ ์—†๊ฒŒ ๋˜์—ˆ๋‹ค... ์•„๋งˆ 2์›” 3์ผ ์ค‘์œผ๋กœ ๋ฐฐํฌ๋  ๋“ฏํ•˜๋‹ค...

์ฒซ ๋Ÿฌ์ŠคํŠธ ํ”„๋กœ์ ํŠธ์ธ๋ฐ ์ƒ๊ฐ๋ณด๋‹ค ์žฌ๋ฐŒ์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  trait์ด๋ผ๋Š” ๊ฐœ๋…์ด ๊ต‰์žฅํžˆ ๋งค๋ ฅ์ ์ด๋‹ค.