찾다
웹 프론트엔드CSS 튜토리얼Nodejs 및 GraphQL로 자신의 인증 API를 만들어 보자.

Nodejs 및 GraphQL로 자신의 인증 API를 만들어 봅시다.

인증은 GraphQL을 처음 접하는 개발자에게 가장 어려운 작업 중 하나입니다. 설정하기 쉬운 ORM 선택, 안전한 토큰 및 해시 비밀번호를 생성하는 방법, HTTP 라이브러리를 사용할 수있는 방법 및 사용 방법을 포함하여 많은 기술적 고려 사항이 포함되어 있습니다.

이 기사는 지역 인증 에 중점을 둡니다. 이는 최신 웹 사이트가 인증을 처리하는 가장 인기있는 방법 일 것입니다. 이는 Google 인증 사용과 달리 사용자의 이메일비밀번호를 요청하여 달성됩니다.

또한이 기사에서는 Apollo Server 2, JWT (JSON Web Tokens) 및 ORM 속도를 사용하여 Node.js Authentication API를 구축합니다.

인증 처리

시스템에 로그인 :

  • 인증은 사용자를 식별하거나 인증합니다.
  • 인증 된 사용자가 액세스 할 수있는 경로 (또는 응용 프로그램의 일부)의 확인을 승인합니다 .

이 프로세스를 구현하는 단계는 다음과 같습니다.

  1. 사용자는 비밀번호 및 이메일로 등록합니다.
  2. 사용자의 자격 증명은 데이터베이스에 저장됩니다.
  3. 등록이 완료되면 사용자가 로그인 페이지로 리디렉션됩니다.
  4. 인증 후 사용자에게 특정 리소스에 대한 액세스 권한이 부여됩니다.
  5. 사용자의 상태는 모든 브라우저 스토리지 매체 (예 : 로컬 스토리지, 쿠키, 세션) 또는 JWT에 저장됩니다.

전제 조건

더 깊이 가기 전에 다음은 따라야 할 몇 가지 단계가 있습니다.

  • node.js 6 이상
  • 원사 (권장) 또는 NPM
  • 그래프 QL 놀이터
  • GraphQL 및 Node.js의 기본 사항
  • … 지식을 추구하는 마음!

의존성

다음은 긴 목록입니다. 시작하겠습니다.

  • Apollo Server : 모든 유형의 GraphQL 클라이언트와 호환되는 오픈 소스 GraphQL 서버. 이 프로젝트에서는 Express를 서버로 사용하지 않습니다. 대신, 우리는 GraphQL API를 노출시키기 위해 Apollo Server의 기능을 활용할 것입니다.
  • bcryptjs : 사용자 비밀번호를 데이터베이스에 해시 하고자합니다. 그래서 우리는 Bcrypt를 사용할 것입니다. Web Crypto API 의 getRandomValues ​​인터페이스에 의존하여 안전한 임의의 숫자를 얻습니다.
  • dotenv : 우리는 dotenv를 사용하여 .env 파일에서 환경 변수를로드합니다.
  • JSONWEBTOKE : 사용자가 로그인 한 후 각 후속 요청에는 JWT가 포함되어 사용자가 토큰을 사용할 수있는 경로, 서비스 및 리소스에 액세스 할 수 있습니다. JSONWEBTOKE는 사용자의 신원을 확인하는 데 사용되는 JWT를 생성하는 데 사용됩니다.
  • NODEMON : 디렉토리 변경이 감지 될 때 노드 응용 프로그램을 자동으로 다시 시작하여 노드 기반 애플리케이션을 개발하는 데 도움이되는 도구입니다. 코드가 변경 될 때마다 서버가 종료되고 시작되기를 원하지 않습니다. Nodemon은 매번 응용 프로그램의 변경 사항을 확인하고 서버를 자동으로 다시 시작합니다.
  • mysql2 : node.js의 SQL 클라이언트. 마이그레이션을 실행할 수 있도록 SQL 서버에 연결해야합니다.
  • 속도 : 속도는 Postgres, MySQL, MariaDB, SQLite 및 Microsoft SQL Server에 사용되는 약속 기반 노드 ORM입니다. 우리는 속도를 사용하여 마이그레이션과 모델을 자동으로 생성 할 것입니다.
  • 속도 CLI : 후속 화 CLI를 사용하여 속편 명령을 실행합니다. 원사 추가-글로벌 속편 CLI를 사용하여 터미널에 전역으로 설치하십시오.

디렉토리 구조 및 개발 환경 설정

새로운 프로젝트를 만들어 봅시다. 새 폴더를 만들고 다음을 작성하십시오.

 <code>yarn init -y</code>

-y 플래그는 모든 원사 init 문제에 대해 예를 선택하고 기본값을 사용한다는 것을 의미합니다.

또한 폴더에 package.json 파일을 배치해야하므로 프로젝트 종속성을 설치하겠습니다.

 <code>yarn add apollo-server bcryptjs dotenv jsonwebtoken nodemon sequelize sqlite3</code>

다음으로 개발 환경에 바벨을 추가합시다.

 <code>yarn add babel-cli babel-preset-env babel-preset-stage-0 --dev</code>

이제 바벨을 구성합시다. 터미널에서 .babelrc를 터치합니다. 이렇게하면 다음을 추가 할 바벨 구성 파일을 생성하고 엽니 다.

 <code>{ "presets": ["env", "stage-0"] }</code>

서버가 데이터를 시작하고 마이그레이션하면 더 나을 것입니다. 다음과 함께 Package.json을 업데이트하여 자동으로이를 수행 할 수 있습니다.

 <code>"scripts": { "migrate": " sequelize db:migrate", "dev": "nodemon src/server --exec babel-node -e js", "start": "node src/server", "test": "echo \"Error: no test specified\" && exit 1" },</code>

다음은 현재 완전한 package.json 파일입니다.

 <code>{ "name": "graphql-auth", "version": "1.0.0", "main": "index.js", "scripts": {  "migrate": " sequelize db:migrate",  "dev": "nodemon src/server --exec babel-node -e js",  "start": "node src/server",  "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": {  "apollo-server": "^2.17.0",  "bcryptjs": "^2.4.3",  "dotenv": "^8.2.0",  "jsonwebtoken": "^8.5.1",  "nodemon": "^2.0.4",  "sequelize": "^6.3.5",  "sqlite3": "^5.0.0" }, "devDependencies": {  "babel-cli": "^6.26.0",  "babel-preset-env": "^1.7.0",  "babel-preset-stage-0": "^6.24.1" } }</code>

개발 환경이 설정되었으므로 데이터베이스로 이동하겠습니다.

데이터베이스 설정

우리는 MySQL을 데이터베이스로 사용하고 관계 매핑을 위해 Sequelize ORM을 사용합니다. 속편을 실행하십시오 (전 세계적으로 설치했다고 가정). 이 명령은 /config /models 및 /migrations의 세 가지 폴더를 생성해야합니다. 현재 프로젝트 디렉토리 구조가 형성되고 있습니다.

데이터베이스를 구성하겠습니다. 먼저 프로젝트 루트 디렉토리에서 .env 파일을 만들고 다음을 붙여 넣습니다.

 <code>NODE_ENV=development DB_HOST=localhost DB_USERNAME= DB_PASSWORD= DB_NAME=</code>

그런 다음 방금 만든 /config 폴더로 이동하여 config.json 파일의 이름을 config.js로 바꿉니다. 그런 다음 다음 코드를 넣습니다.

 <code>require('dotenv').config() const dbDetails = { username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, host: process.env.DB_HOST, dialect: 'mysql' } module.exports = { development: dbDetails, production: dbDetails }</code>

여기서 .env 파일에서 설정 한 데이터베이스 세부 정보를 읽고 있습니다. Process.env는 시스템 환경의 현재 상태를 나타내는 노드에 의해 주입 된 전역 변수입니다.

데이터베이스 세부 정보를 적절한 데이터로 업데이트하겠습니다. SQL 데이터베이스를 열고 GraphQL_Auth라는 테이블을 만듭니다. Laragon을 로컬 서버로 사용하고 Phpmyadmin을 사용하여 데이터베이스 테이블을 관리합니다.

사용하든 최신 정보로 .env 파일을 업데이트해야합니다.

 <code>NODE_ENV=development DB_HOST=localhost DB_USERNAME=graphql_auth DB_PASSWORD= DB_NAME=</code>

속편을 구성합시다. 프로젝트의 루트 디렉토리에 .sequelizerc 파일을 만들고 다음을 붙여 넣습니다.

 <code>const path = require('path') module.exports = { config: path.resolve('config', 'config.js') }</code>

이제 구성을 모델에 통합하겠습니다. /models 폴더에서 index.js로 이동하여 구성 변수를 편집하십시오.

 <code>const config = require(__dirname '/../../config/config.js')[env]</code>

마지막으로 모델을 작성해 봅시다. 이 프로젝트에는 사용자 모델이 필요합니다. 속편을 사용하여 모델을 자동으로 생성하겠습니다. 다음은 터미널에서 실행 해야하는 내용입니다.

 <code>sequelize model:generate --name User --attributes username:string,email:string,password:string</code>

우리를 위해 생성하는 모델을 편집합시다. /Models 폴더에서 user.js로 이동하여 다음을 붙여 넣습니다.

 <code>'use strict'; module.exports = (sequelize, DataTypes) => { const User = sequelize.define('User', {  username: {   type: DataTypes.STRING,  },  email: {   type: DataTypes.STRING,   },  password: {   type: DataTypes.STRING,  } }, {}); return User; };</code>

여기서는 사용자 이름, 이메일 및 비밀번호에 대한 속성 및 필드를 만듭니다. 스키마의 변경 사항을 추적하기 위해 마이그레이션을 실행합시다.

 <code>yarn migrate</code>

이제 패턴과 파서를 쓰자.

Schema 및 Parser를 GraphQL Server와 통합하십시오

이 섹션에서는 패턴을 정의하고 구문 분석 기능을 작성하여 서버에 노출시킵니다.

모델

SRC 폴더에서 /schema라는 새 폴더를 만들고 schema.js라는 파일을 만듭니다. 다음 코드를 붙여 넣습니다.

 <code>const { gql } = require('apollo-server') const typeDefs = gql` type User {  id: Int!  username: String  email: String! } type AuthPayload {  token: String!  user: User! } type Query {  user(id: Int!): User  allUsers: [User!]!  me: User } type Mutation {  registerUser(username: String, email: String!, password: String!): AuthPayload!  login (email: String!, password: String!): AuthPayload! } ` module.exports = typeDefs</code>

여기서 Apollo-Server에서 GraphQL-Tag를 가져옵니다. Apollo Server는 GQL로 패턴을 랩핑해야합니다.

파서

SRC 폴더에서 /Resolvers라는 새 폴더를 작성하고 resolver.js라는 파일을 만듭니다. 다음 코드를 붙여 넣습니다.

 <code>const bcrypt = require('bcryptjs') const jsonwebtoken = require('jsonwebtoken') const models = require('../models') require('dotenv').config() const resolvers = {  Query: {   async me(_, args, { user }) {    if(!user) throw new Error('You are not authenticated')    return await models.User.findByPk(user.id)   },   async user(root, { id }, { user }) {    try {     if(!user) throw new Error('You are not authenticated!')     return models.User.findByPk(id)    } catch (error) {     throw new Error(error.message)    }   },   async allUsers(root, args, { user }) {    try {     if (!user) throw new Error('You are not authenticated!')     return models.User.findAll()    } catch (error) {     throw new Error(error.message)    }   }  },  Mutation: {   async registerUser(root, { username, email, password }) {    try {     const user = await models.User.create({      username,      email,      password: await bcrypt.hash(password, 10)     })     const token = jsonwebtoken.sign(      { id: user.id, email: user.email},      process.env.JWT_SECRET,      { expiresIn: '1y' }     )     return {      token, id: user.id, username: user.username, email: user.email, message: "Authentication succesfull"     }    } catch (error) {     throw new Error(error.message)    }   },   async login(_, { email, password }) {    try {     const user = await models.User.findOne({ where: { email }})     if (!user) {      throw new Error('No user with that email')     }     const isValid = await bcrypt.compare(password, user.password)     if (!isValid) {      throw new Error('Incorrect password')     }     // return jwt     const token = jsonwebtoken.sign(      { id: user.id, email: user.email},      process.env.JWT_SECRET,      { expiresIn: '1d'}     )     return {      token, user     }   } catch (error) {    throw new Error(error.message)   }  } }, } module.exports = resolvers</code>

코드가 많이 있습니다. 거기서 무슨 일이 일어나고 있는지 봅시다.

먼저 모델, bcrypt 및 jsonwebtoken을 가져온 다음 환경 변수를 초기화합니다.

다음은 파서 기능입니다. 쿼리 파서에는 세 가지 기능 (Me, User 및 Allusers)이 있습니다.

  • ME 현재 로그인 한 사용자의 자세한 정보를 얻으려면 쿼리. 사용자 객체를 컨텍스트 매개 변수로 받아들입니다. 컨텍스트는 쿼리에 제공된 ID를 통해 사용자 데이터를로드하는 데 사용되는 데이터베이스에 대한 액세스를 제공하는 데 사용됩니다.
  • 사용자 쿼리는 사용자의 ID를 기반으로 사용자의 자세한 정보를 얻습니다. ID를 컨텍스트 매개 변수 및 사용자 객체로 허용합니다.
  • Alluser 쿼리는 모든 사용자의 세부 사항을 반환합니다.

사용자 상태가 로그인되면 사용자는 객체가됩니다. 사용자가 로그인되지 않으면 사용자가 null이됩니다. 우리는 돌연변이 에이 사용자를 만들 것입니다.

돌연변이 파서에는 두 가지 기능 (레지스터 및 로그 라이너)이 있습니다.

  • Registeruser는 사용자의 사용자 이름, 이메일 및 비밀번호를 수락 하고이 필드를 사용하여 데이터베이스에서 새 행을 만듭니다. bcryptjs 패키지를 사용하여 bcrypt.hash (Password, 10)를 사용하여 사용자의 암호를 해시하기 위해 사용합니다. JSONWEBTOKEN.Sign Sign은 주어진 페이로드를 JSON 웹 토큰 문자열 (이 경우 사용자 ID 및 이메일)에 동기로 서명합니다. 마지막으로, RegisterUser는 성공하면 JWT 문자열과 사용자 프로필을 반환합니다. 오류가 발생하면 오류 메시지가 반환됩니다.
  • 로그인은 이메일 및 비밀번호를 수락하고 이러한 세부 사항이 제공된 세부 정보와 일치하는지 확인합니다. 먼저, 이메일 값이 이미 사용자 데이터베이스 어딘가에 있는지 확인합니다.
 <code>models.User.findOne({ where: { email }}) if (!user) { throw new Error('No user with that email') }</code>

그런 다음 Bcrypt의 bcrypt.compare 방법을 사용하여 암호가 일치하는지 확인합니다.

 <code>const isValid = await bcrypt.compare(password, user.password) if (!isValid) { throw new Error('Incorrect password') }</code>

그런 다음 이전에 Registeruser에서했던 것처럼 jsonwebtoken.sign을 사용하여 JWT 문자열을 생성합니다. 로그인 돌연변이는 토큰 및 사용자 객체를 반환합니다.

이제 .env 파일에 JWT_SECRET을 추가하겠습니다.

 <code>JWT_SECRET=一个非常长的秘密</code>

섬기는 사람

마지막으로 서버입니다! 프로젝트의 루트 폴더에서 Server.js를 생성하고 다음을 붙여 넣습니다.

 <code>const { ApolloServer } = require('apollo-server') const jwt =  require('jsonwebtoken') const typeDefs = require('./schema/schema') const resolvers = require('./resolvers/resolvers') require('dotenv').config() const { JWT_SECRET, PORT } = process.env const getUser = token => { try {  if (token) {   return jwt.verify(token, JWT_SECRET)  }  return null } catch (error) {  return null } } const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => {  const token = req.get('Authorization') || ''  return { user: getUser(token.replace('Bearer', ''))} }, introspection: true, playground: true }) server.listen({ port: process.env.PORT || 4000 }).then(({ url }) => { console.log(`? Server ready at ${url}`); });</code>

여기서 우리는 스키마, Resolvers 및 JWT를 가져 와서 환경 변수를 초기화합니다. 먼저 확인을 사용하여 JWT 토큰을 확인합니다. jwt.verify 토큰 및 JWT 키를 매개 변수로 허용합니다.

다음으로 TypEdefs 및 Resolvers를 수락하는 Apolloserver 인스턴스를 사용하여 서버를 만듭니다.

서버가 있습니다! 터미널에서 원사 개발을 실행하여 시작합시다.

테스트 API

이제 GraphQL Playground를 사용하여 GraphQL API를 테스트합시다. ID를 통해 개별 사용자를 포함한 모든 사용자를 등록, 로그인 및 볼 수 있어야합니다.

먼저 GraphQL Playground 앱을 열거 나 브라우저에서 LocalHost : // 4000을 열면 액세스 할 것입니다.

등록 된 사용자를위한 돌연변이

 <code>mutation { registerUser(username: "Wizzy", email: "[email protected]", password: "wizzyekpot" ){  token } }</code>

우리는 다음과 같은 결과를 얻어야합니다.

 <code>{ "data": {  "registerUser": {   "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTUsImVtYWlsIjoiZWtwb3RAZ21haWwuY29tIiwiaWF0IjoxNTk5MjQwMzAwLCJleHAiOjE2MzA3OTc5MDB9.gmeynGR9Zwng8cIJR75Qrob9bovnRQT242n6vfBt5PY"  } } }</code>

로그인 돌연변이

이제 방금 만든 사용자 세부 사항으로 로그인하겠습니다.

 <code>mutation { login(email:"[email protected]" password:"wizzyekpot"){  token } }</code>

우리는 다음과 같은 결과를 얻어야합니다.

 <code>{ "data": {  "login": {   "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTUsImVtYWlsIjoiZWtwb3RAZ21haWwuY29tIiwiaWF0IjoxNTk5MjQwMzcwLCJleHAiOjE1OTkzMjY3NzB9.PDiBKyq58nWxlgTOQYzbtKJ-HkzxemVppLA5nBdm4nc"  } } }</code>

기이!

개별 사용자를위한 쿼리

단일 사용자를 쿼리하려면 사용자 토큰을 인증 헤더로 전달해야합니다. HTTP 헤더 탭으로 이동하십시오.

... 그리고이 내용을 다음에 붙여 넣습니다.

 <code>{ "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTUsImVtYWlsIjoiZWtwb3RAZ21haWwuY29tIiwiaWF0IjoxNTk5MjQwMzcwLCJleHAiOjE1OTkzMjY3NzB9.PDiBKyq58nWxlgTOQYzbtKJ-HkzxemVppLA5nBdm4nc" }</code>

다음은 다음과 같습니다.

 <code>query myself{ me {  id  email  username } }</code>

우리는 다음과 같은 결과를 얻어야합니다.

 <code>{ "data": {  "me": {   "id": 15,   "email": "[email protected]",   "username": "Wizzy"  } } }</code>

엄청난! 이제 id로 사용자를 데려 오겠습니다.

 <code>query singleUser{ user(id:15){  id  email  username } }</code>

다음은 모든 사용자를 얻는 쿼리입니다.

 <code>{ allUsers{  id  username  email } }</code>

요약

인증은 인증이 필요한 웹 사이트를 구축 할 때 가장 어려운 작업 중 하나입니다. GraphQL을 사용하면 하나의 엔드 포인트 만 사용하여 완전한 인증 API를 구축 할 수 있습니다. Sequelize ORM을 사용하면 SQL 데이터베이스와 관계를 쉽게 만들 수있어 모델에 대해 걱정할 필요가 거의 없습니다. 또한 HTTP 서버 라이브러리 (예 : Express)가 필요하지 않지만 Apollo GraphQL을 미들웨어로 사용한다는 점도 주목할 가치가 있습니다. Apollo Server 2는 이제 우리가 자신의 라이브러리 독립적 인 GraphQL 서버를 만들 수 있습니다!

GitHub 에서이 자습서의 소스 코드를 확인하십시오.

위 내용은 Nodejs 및 GraphQL로 자신의 인증 API를 만들어 보자.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
마우스 움직임을 시뮬레이션합니다마우스 움직임을 시뮬레이션합니다Apr 22, 2025 am 11:45 AM

라이브 토크 나 수업 중에 대화식 애니메이션을 표시해야한다면 슬라이드와 상호 작용하기가 항상 쉽지 않다는 것을 알 수 있습니다.

Astro Actions 및 Fuse.js로 검색을 전원합니다Astro Actions 및 Fuse.js로 검색을 전원합니다Apr 22, 2025 am 11:41 AM

Astro를 사용하면 빌드 중에 대부분의 사이트를 생성 할 수 있지만 Fuse.js와 같은 것을 사용하여 검색 기능을 처리 할 수있는 작은 서버 측 코드가 있습니다. 이 데모에서는 퓨즈를 사용하여 개인 "북마크"세트를 검색합니다.

정의되지 않은 : 세 번째 부울 가치정의되지 않은 : 세 번째 부울 가치Apr 22, 2025 am 11:38 AM

문서가 저장되는 동안 Google 문서에서 볼 수있는 것과 유사한 프로젝트 중 하나에서 알림 메시지를 구현하고 싶었습니다. 다시 말해, a

제 3의 진술의 방어에서제 3의 진술의 방어에서Apr 22, 2025 am 11:25 AM

몇 달 전에 나는 해커 뉴스를 썼고 (하나와 마찬가지로) IF 문을 사용하지 않는 것에 대한 (현재 삭제 된) 기사를 가로 질러 달렸습니다. 이 아이디어를 처음 접한다면 (나처럼

다국어 번역에 웹 스피치 API 사용다국어 번역에 웹 스피치 API 사용Apr 22, 2025 am 11:23 AM

공상 과학 소설의 초기부터 우리는 우리와 대화하는 기계에 대해 환상을 가지고 있습니다. 오늘은 평범합니다. 그럼에도 불구하고 제작 기술

Jetpack Gutenberg 블록Jetpack Gutenberg 블록Apr 22, 2025 am 11:20 AM

Gutenberg가 핵심으로 풀려 났을 때를 기억합니다. 왜냐하면 나는 그날 WordCamp에 있었기 때문입니다. 지금은 몇 달이 지났으므로 점점 더 많은 것을 상상합니다.

VUE에서 재사용 가능한 페이지 매김 구성 요소 생성VUE에서 재사용 가능한 페이지 매김 구성 요소 생성Apr 22, 2025 am 11:17 AM

대부분의 웹 애플리케이션의 배후에있는 아이디어는 데이터베이스에서 데이터를 가져 와서 최상의 방법으로 사용자에게 제시하는 것입니다. 우리가 거기에서 데이터를 다룰 때

'Box Shadows'와 Clip-Path를 함께 사용합니다'Box Shadows'와 Clip-Path를 함께 사용합니다Apr 22, 2025 am 11:13 AM

#039;는 당신이 의미있는 것처럼 보일 수있는 상황에 대한 약간의 단계를 수행하자. 이것에서

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 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경

mPDF

mPDF

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

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

PhpStorm 맥 버전

PhpStorm 맥 버전

최신(2018.2.1) 전문 PHP 통합 개발 도구

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구