찾다
웹 프론트엔드JS 튜토리얼nodejs에서 JWT를 사용하는 방법에 대한 간략한 분석?

이 기사에서는 JWT를 이해하고 노드에서 JWT를 적용하는 방법과 JWT의 장점과 단점을 소개합니다. 모든 사람에게 도움이 되기를 바랍니다.

nodejs에서 JWT를 사용하는 방법에 대한 간략한 분석?

JWT란 무엇입니까

JWT는 JSON Web Token의 약어로, 기존 인증 메커니즘에서는 몇 가지 단계만 거치면 됩니다.

1. 用户将账号密码发送到服务器;

2. 服务器通过验证账号密码后,会在当前session中保存一些用户相关的信息,用户角色或者过期时间等等;

3. 服务器给用户一个session_id, 写入用户的Cookie或者客户端自行保存在本地;

4. 用户每次请求服务,都需要带上这个session_id,或许会通过Cookie,或者其他的方式;

5. 服务器接收到后,回去数据库查询当前的session_id,校验该用户是否有权限;

이 모델의 한 가지 장점은 서버가 언제든지 사용자의 권한을 종료할 수 있고 데이터베이스로 이동하여 현재 사용자의 세션 정보를 수정하거나 삭제할 수 있다는 것입니다. 그러나 단점도 있습니다. 즉, 서버 클러스터인 경우 각 서버가 동일한 세션 저장 정보를 얻을 수 있도록 모든 시스템이 세션 정보를 공유해야 한다는 것입니다. 이러한 문제는 해결될 수 있지만 작업량이 엄청납니다.

JWT 솔루션의 장점은 이 정보가 저장되지 않는다는 것입니다. 토큰 데이터는 요청이 수락될 때마다 확인만 하면 됩니다. [관련 튜토리얼 추천 : nodejs 동영상 튜토리얼, 프로그래밍 교육]

JWT의 원리

JWT의 원리에 대해 간단히 말씀드리겠습니다. 실제로 클라이언트가 인증 요청을 보내면 서버가 사용자를 인증한 후 생성합니다. JSON 객체에는 "당신은 누구입니까, 무엇을 하는가?, 만료 시간"과 같은 정보가 포함될 수 있습니다. 중요한 것은 만료 시간이 있어야 한다는 것입니다.

{
    username: "贼烦字符串er",
    role: "世代码农",
    endTime: "2022年5月20日"
}

하지만 이렇게 사용되지는 않습니다. 가역적 서명 알고리즘을 통해 서명되어 전송되며 제출한 페이로드의 일부 정보는 사진을 사용하여 표시됩니다. 일반 형식:

nodejs에서 JWT를 사용하는 방법에 대한 간략한 분석?

그림을 사용할 수 있습니다. 반환된 정보는 대략 세 부분으로 나누어져 있음을 알 수 있습니다. 왼쪽은 서명 후 결과이고 오른쪽은 클라이언트에게 반환된 결과입니다. 또한 디코딩된 소스 코드의 세 부분은 "점"으로 구분되며 빨간색으로 구분되며 보라색과 파란색의 세 가지 색상은 1:1로 대응됩니다.

  • 첫 번째 빨간색 부분은 주로 헤더입니다. . 그림의 서명 알고리즘(default HS256)은 SHA-256을 사용하는 HMAC입니다. 이는 대칭 알고리즘이며 두 당사자 간에 하나의 키만 공유되며 typ 필드는 JWT 유형으로 표시됩니다. 두 번째 보라색 부분 페이로드는 전송될 실제 데이터인 JSON 객체입니다. 7개의 공식 데이터가 있습니다. 사용할 수 있는 필드:

  • iss(발행자): 발행자

    exp(만료 시간): 만료 시간
    • sub (제목) : 제목
    • aud (청중) : 청중
    • nbf (Not Before) : 유효 시간
    • iat (Issued At) : 발급 시간
    • jti (JWT ID) : 번호
    • 이외에 JWT는 기본적으로 암호화되지 않으므로 일부 민감한 데이터를 사용하지 않도록 주의하세요.

세 번째 부분은 Signature 서명입니다. 이 부분은 본인이 지정한 비밀키로 서버에만 존재하며, 헤더에 지정된 알고리즘을 사용하여 다음 서명을 통해 서명합니다. 방법.

  • Signature签名,这一部分,是由你自己指定且只有服务器存在的秘钥,然后使用头部指定的算法通过下面的签名方法进行签名。

JWT的简单使用

下面我们来感受一下具体的使用:

第一步:我们需要搭建一个node的项目;通过npm init -y初始化一个项目;之后我们需要安装依赖,分别按状expressjsonwebtokennodemon三个依赖:

$ npm i express jsonwebtoken nodemon

之后在package.json中的scripts字段中添加nodemon app.js命令:

"scripts": {
    "start": "nodemon app.js"
},

第二步:初始化一下node应用,在根目录下创建app.js文件;

// app.js

const express = require("express");
const app = express();

app.use(express.json());

app.listen(3000, () => {
  console.log(3000 + " listening..."); // 监听3000端口
});

第三步:引入jsonwebtoken依赖,并且创建接口和服务器的私钥;

// app.js

//...
const jwt = require("jsonwebtoken");

const jwtKey = "~!@#$%^&*()+,";
// ...

这里面的jwtKey是我们自定义保存仅限保存在服务器中的私钥,之后我们开始写一个 /login 接口,用来登录,并且创建本地的模拟数据库用来校验,并通过jwt.sign方法进行校验签名:

// app.js
const database = {
  username: "username",
  password: "password",
};

app.post("/login", (req, res) => {
  const { username, password } = req.body;
  if (username === database.username && password === database.password) {
    jwt.sign(
      {
        username,
      },
      jwtKey,
      {
        expiresIn: "30S",
      },
      (_, token) => {
        res.json({
          username,
          message: "登陆成功",
          token,
        });
      }
    );
  }
});

上面代码中我们创建了database变量来模拟创建了本地的账号密码数据库,用来校验登陆;接下来建立了一个/loginpost接口,在校验账号密码完全匹配之后,我们通过jsonwebtoken包导入的jwt对象下的人signJWT의 간단한 사용

🎜🎜구체적인 사용을 경험해 보겠습니다.🎜🎜1단계: 🎜node🎜 프로젝트를 빌드해야 합니다. npm init -y를 통해 초기화합니다. 그런 다음 express, jsonwebtokennodemon과 같은 종속성을 각각 설치해야 합니다. 🎜
export function sign(
    payload: string | Buffer | object,
    secretOrPrivateKey: Secret,
    options?: SignOptions,
): string;

export function sign(
    payload: string | Buffer | object,
    secretOrPrivateKey: Secret,
    callback: SignCallback,
): void;

export function sign(
    payload: string | Buffer | object,
    secretOrPrivateKey: Secret,
    options: SignOptions,
    callback: SignCallback,
): void;
🎜 그런 다음 <code>nodemon을 추가합니다. package.json의 <code>scripts 필드에 있는 app.js 명령: 🎜
export interface SignOptions {
    algorithm?: Algorithm | undefined;
    keyid?: string | undefined;
    expiresIn?: string | number | undefined;
    /** expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms.js).  Eg: 60, "2 days", "10h", "7d" */
    notBefore?: string | number | undefined;
    audience?: string | string[] | undefined;
    subject?: string | undefined;
    issuer?: string | undefined;
    jwtid?: string | undefined;
    mutatePayload?: boolean | undefined;
    noTimestamp?: boolean | undefined;
    header?: JwtHeader | undefined;
    encoding?: string | undefined;
}
🎜2단계: 노드 애플리케이션을 초기화하고 루트 디렉터리 app.js 파일에 생성합니다. 🎜
POST http://localhost:3000/login
content-type: application/json

{
  "username": "username",
  "password": "password"
}
🎜3단계: jsonwebtoken 종속성을 도입하고 인터페이스와 서버의 개인 키를 만듭니다. 🎜
app.get("/afterlogin", (req, res) => {
  const { headers } = req;
  
  const token = headers["authorization"].split(" ")[1];
  // 将token放在header的authorization字段中
  jwt.verify(token, jwtKey, (err, payload) => {
    if (err) return res.sendStatus(403);
    res.json({ message: "认证成功", payload });
  });
});
🎜여기의 jwtKey는 사용자 정의입니다. 개인 키만 저장됩니다. 그런 다음 로그인을 위한 /login 인터페이스 작성을 시작하고 검증을 위한 로컬 시뮬레이션 데이터베이스를 생성한 후 jwt.sign 검증 서명 방법을 통해 검증했습니다.
// 有四个接口签名,可以自行查文档

export function verify(
    token: string,
    // 需要检验的token
    secretOrPublicKey: Secret | GetPublicKeyOrSecret,
    // 定义在服务器的签名秘钥
    callback?: VerifyCallback<JwtPayload | string>,
    // 获取校验信息结果的回调
): void;
🎜위 코드에서는 로그인을 확인하기 위해 로컬 계정 및 비밀번호 데이터베이스 생성을 시뮬레이션하기 위해 database 변수를 생성한 다음 /login의 post 인터페이스, 계정과 비밀번호가 완전히 일치하는지 확인한 후 jsonwebtoken 패키지를 사용하여 jwt 개체 아래에 개인의 sign을 가져옵니다. 서명 방법, 이 방법에는 세 가지 인터페이스 서명이 있습니다. 🎜
export function sign(
    payload: string | Buffer | object,
    secretOrPrivateKey: Secret,
    options?: SignOptions,
): string;

export function sign(
    payload: string | Buffer | object,
    secretOrPrivateKey: Secret,
    callback: SignCallback,
): void;

export function sign(
    payload: string | Buffer | object,
    secretOrPrivateKey: Secret,
    options: SignOptions,
    callback: SignCallback,
): void;

这里用到了函数重载的方式实现接口,我们这里将实现最后一个接口签名,第一个参数可以是一个自定义的对象类型,也可以是一个Buffer类型,还可以直接是一个string类型,我们的源码使用了object类型,自定义了一些字段,因为jwt在进行签名是也会对这些数据一并进行签名,但是值得注意的是,这里尽量不要使用敏感数据,因为JWT默认是不加密的,它的核心就是签名,保证数据未被篡改,而检查签名的过程就叫做验证

当然你也可以对原始Token进行加密后传输;

第二个参数:是我们保存在服务器用来签名的秘钥,通常在客户端-服务端模式中,JWS 使用 JWA 提供的 HS256 算法加上一个密钥即可,这种方式严格依赖密钥,但在分布式场景,可能多个服务都需要验证JWT,若要在每个服务里面都保存密钥,那么安全性将会大打折扣,要知道,密钥一旦泄露,任何人都可以随意伪造JWT。

第三个参数:是签名的选项SignOptions,接口的签名:

export interface SignOptions {
    algorithm?: Algorithm | undefined;
    keyid?: string | undefined;
    expiresIn?: string | number | undefined;
    /** expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms.js).  Eg: 60, "2 days", "10h", "7d" */
    notBefore?: string | number | undefined;
    audience?: string | string[] | undefined;
    subject?: string | undefined;
    issuer?: string | undefined;
    jwtid?: string | undefined;
    mutatePayload?: boolean | undefined;
    noTimestamp?: boolean | undefined;
    header?: JwtHeader | undefined;
    encoding?: string | undefined;
}

这里我们用的是expiresIn字段,指定了时效时间,使用方法参考这个文档;

第四个参数是一个回调,回调的第二个参数就是我们通过签名生成的token,最后将这个token返回给前端,以便存储到前端本地每次请求是带上到服务端进行验证。

接下来,我们来验证一下这个接口: 我是在vscode安装的REST Client插件,之后在根目录创建一个request.http的文件,文件内写上请求的信息:

POST http://localhost:3000/login
content-type: application/json

{
  "username": "username",
  "password": "password"
}

之后在命令行执行npm run start命令启动服务,之后在requset.http文件上方点击Send Request按钮,发送请求:

nodejs에서 JWT를 사용하는 방법에 대한 간략한 분석?

请求成功后,会看到这样的响应报文:

nodejs에서 JWT를 사용하는 방법에 대한 간략한 분석?

token字段就是我们JWT生成的token;

下面来验证一下这个token是否有效,我们在写一个登录过后的接口:

app.get("/afterlogin", (req, res) => {
  const { headers } = req;
  
  const token = headers["authorization"].split(" ")[1];
  // 将token放在header的authorization字段中
  jwt.verify(token, jwtKey, (err, payload) => {
    if (err) return res.sendStatus(403);
    res.json({ message: "认证成功", payload });
  });
});

这段代码中,通过获取请求头中的authorization字段中的token进行获取之前通过JWT生成的token。 之后通过调用jwt.verify校验方法校验这个token是否有效,这个方法分别有三个参数:

// 有四个接口签名,可以自行查文档

export function verify(
    token: string,
    // 需要检验的token
    secretOrPublicKey: Secret | GetPublicKeyOrSecret,
    // 定义在服务器的签名秘钥
    callback?: VerifyCallback<JwtPayload | string>,
    // 获取校验信息结果的回调
): void;

接下来我们把刚才响应的token复制到请求头中:

###
GET http://localhost:3000/afterlogin
authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXJuYW1lIiwiaWF0IjoxNjUyNzg5NzA3LCJleHAiOjE2NTI3ODk3Mzd9.s9fk3YLhxTUcpUgCfIK4xQN58Hk_XEP5y9GM9A8jBbY

前面的Bearer认证, 是http协议中的标准认证方式

同样点击Send Request当看到下面图片的响应,就意味着响应成功:

nodejs에서 JWT를 사용하는 방법에 대한 간략한 분석?

其实以上就是JWT的一些简单的用法,接下来再说一下JWT本身存在的优缺点.

JWT的不足

  • JWT占用的存储空间其实并不小,如果我们需要签名做过多的信息,那么token很可能会超出cookie的长度限制,例如对比一下这两张图片:

nodejs에서 JWT를 사용하는 방법에 대한 간략한 분석?

很明显,随着payload的信息量增大,token的长度也会增加;

  • 安全性,其实如果token的占用空间过大,Cookie最大存储空间只有4kb前端可以存储在localStorage之类的本地存储,但是会带来一个问题,如果不是放在cookie的话,安全性就会大打折扣,就会有通过js脚本获取到的风险,就意味着任何hacker都可以拿着它做任何事情;

  • 不灵活的时效性,其实JWT的某方面意义在于用户token不需要持久化存储,而是采用服务器校验的方式对token进行有效校验,刚才看到了,签名也是把到期时间一并签名的,如果改变到期时间token就会被篡改,由于没有存储和手动更改时效的方法,所以很难立刻将这个token删掉,如果用户重复登陆两次,生成两个token,那么原则上两个token都是有效的;

总结

以上主要讲了几点:

  • JWT의 원리는 주로 서버의 개인 키를 통해 JSON 서명으로 생성된 토큰과 통신하는 것입니다. token进行会话;

  • 也介绍了JWT内部数据的组成,是由Header用来指定签名算法和类型的,payload来传输JSON数据,Signature来对数据进行签名算法,放置篡改;

  • 具体介绍了一下如何通过nodejs使用JWT,通过sign方法进行数据签名,verify方法进行签名验证;

  • 还介绍了一些JWT的不足:

    • 一个是存储空间随着签名数据量的增大而增加;

    • 再有就是安全性,如果由于存储空间过大将无法存储在安全级别相对较高的Cookie中,导致脚本可以随意获取;

    • 再有就是时效性,无法灵活的控制token

    또한 사용되는 JWT의 내부 데이터 구성을 소개합니다. 서명 알고리즘 및 유형에 대해 페이로드는 JSON 데이터를 전송하는 데 사용되며 서명은 변조를 방지하기 위해 데이터에 서명 알고리즘을 수행하는 데 사용됩니다.

nodejs를 통해 JWT를 사용하고 데이터 서명을 수행하는 방법을 구체적으로 소개합니다. sign 메소드를 통해 서명 확인을 위한 verify 메소드도 JWT의 몇 가지 단점을 소개합니다.

    하나는 저장공간입니다. 서명데이터의 양이 늘어나면

    그다음은 보안입니다. 저장공간이 너무 크면 쿠키에 저장되지 않습니다. > 비교적 높은 보안 수준으로 인해 스크립트가 마음대로 얻을 수 있습니다.

    🎜그리고 적시성이 있고 토큰의 적시성은 유연하게 제어할 수 없습니다. 🎜🎜🎜참고용으로 위 nodejs의 🎜데모 소스 코드🎜입니다. 🎜🎜https://github.com/wangzi6224/jwt-usage-nodejs🎜🎜🎜노드 관련 지식을 더 보려면 다음을 방문하세요. 🎜nodejs 튜토리얼🎜! 🎜

    위 내용은 nodejs에서 JWT를 사용하는 방법에 대한 간략한 분석?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명
    이 기사는 掘金社区에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
    如何使用ThinkPHP6进行JWT认证?如何使用ThinkPHP6进行JWT认证?Jun 12, 2023 pm 12:18 PM

    JWT(JSONWebToken)是一种轻量级的认证和授权机制,它使用JSON对象作为安全令牌,可以在多个系统之间安全地传输用户身份信息。而ThinkPHP6是一种基于PHP语言的高效、灵活的MVC框架,它提供了许多有用的工具和功能,其中就包括JWT认证机制。在本文中,我们将介绍如何使用ThinkPHP6进行JWT认证,以保障Web应用程序的安全性和可靠

    如何在PHP中使用JWT和JWE进行API身份验证和加密如何在PHP中使用JWT和JWE进行API身份验证和加密Jun 17, 2023 pm 02:42 PM

    随着互联网的发展,越来越多的网站和应用需要提供API接口来进行数据交互。在这种情况下,API身份验证和加密成为了非常重要的问题。而JWT和JWE作为一种流行的身份验证和加密机制,在PHP中的应用也越来越广泛。那么,本文将介绍如何在PHP中使用JWT和JWE进行API身份验证和加密。JWT的基本概念JWT代表JSONWe

    PHP中的安全JWT令牌生成与验证技术解析PHP中的安全JWT令牌生成与验证技术解析Jul 01, 2023 pm 06:06 PM

    PHP中的安全JWT令牌生成与验证技术解析随着网络应用的发展,用户身份验证和授权变得越来越重要。JsonWebToken(JWT)是一种用于在网络应用中安全传输信息的开放标准(RFC7519)。在PHP开发中,使用JWT令牌来实现用户身份验证和授权已成为一种常见的做法。本文将介绍PHP中的安全JWT令牌生成与验证技术。一、JWT基础知识在了解如何生成与

    PHP中的OAuth:创建一个JWT授权服务器PHP中的OAuth:创建一个JWT授权服务器Jul 28, 2023 pm 05:27 PM

    PHP中的OAuth:创建一个JWT授权服务器随着移动应用和前后端分离的趋势的兴起,OAuth成为了现代Web应用中不可或缺的一部分。OAuth是一种授权协议,通过提供标准化的流程和机制,用于保护用户的资源免受未经授权的访问。在本文中,我们将学习如何使用PHP创建一个基于JWT(JSONWebTokens)的OAuth授权服务器。JWT是一种用于在网络中

    node爬取数据实例:聊聊怎么抓取小说章节node爬取数据实例:聊聊怎么抓取小说章节May 02, 2022 am 10:00 AM

    node怎么爬取数据?下面本篇文章给大家分享一个node爬虫实例,聊聊利用node抓取小说章节的方法,希望对大家有所帮助!

    Vue.js实现登录验证的完整指南(API、JWT、axios)Vue.js实现登录验证的完整指南(API、JWT、axios)Jun 09, 2023 pm 04:04 PM

    Vue.js是一种流行的JavaScript框架,用于构建动态Web应用程序。实现用户登录验证是开发Web应用程序的必要部分之一。本文将介绍使用Vue.js、API、JWT和axios实现登录验证的完整指南。创建Vue.js应用程序首先,我们需要创建一个新的Vue.js应用程序。我们可以使用VueCLI或手动创建一个Vue.js应用程序。安装axiosax

    深入解析JWT(JSON Web Token)的原理及用法深入解析JWT(JSON Web Token)的原理及用法Jan 10, 2023 am 10:55 AM

    本篇文章给大家带来了关于JWT的相关知识,其中主要介绍了什么是JWT?JWT的原理以及用法是什么?感兴趣的朋友,下面一起来看一下吧,希望对大家有帮助。

    如何使用JWT在PHP应用中实现身份验证和授权如何使用JWT在PHP应用中实现身份验证和授权Aug 03, 2023 pm 10:17 PM

    如何使用JWT在PHP应用中实现身份验证和授权引言:随着互联网的快速发展,身份验证和授权在Web应用程序中变得日益重要。JSONWebToken(JWT)是一种流行的认证和授权机制,它在PHP应用中广泛应用。本文将介绍如何使用JWT在PHP应用中实现身份验证和授权,并提供代码示例,帮助读者更好地理解JWT的使用方法。一、JWT简介JSONWebTo

    See all articles

    핫 AI 도구

    Undresser.AI Undress

    Undresser.AI Undress

    사실적인 누드 사진을 만들기 위한 AI 기반 앱

    AI Clothes Remover

    AI Clothes Remover

    사진에서 옷을 제거하는 온라인 AI 도구입니다.

    Undress AI Tool

    Undress AI Tool

    무료로 이미지를 벗다

    Clothoff.io

    Clothoff.io

    AI 옷 제거제

    AI Hentai Generator

    AI Hentai Generator

    AI Hentai를 무료로 생성하십시오.

    뜨거운 도구

    드림위버 CS6

    드림위버 CS6

    시각적 웹 개발 도구

    SecList

    SecList

    SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

    안전한 시험 브라우저

    안전한 시험 브라우저

    안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

    에디트플러스 중국어 크랙 버전

    에디트플러스 중국어 크랙 버전

    작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

    mPDF

    mPDF

    mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.