跳至內容
正在從 NextAuth.js v4 遷移?請閱讀 我們的遷移指南.

Dgraph 轉接器

資源

設定

安裝

npm install @auth/dgraph-adapter

環境變數

AUTH_DGRAPH_GRAPHQL_ENDPOINT=https://127.0.0.1:8080/graphql
AUTH_DGRAPH_GRAPHQL_KEY=abc123

設定

./auth.ts
import NextAuth from "next-auth"
import { DgraphAdapter } from "@auth/dgraph-adapter"
 
export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [],
  adapter: DgraphAdapter({
    endpoint: process.env.AUTH_DGRAPH_GRAPHQL_ENDPOINT,
    authToken: process.env.AUTH_DGRAPH_GRAPHQL_KEY,
    // you can omit the following properties if you are running an unsecure schema
    authHeader: process.env.AUTH_HEADER, // default: "Authorization",
    jwtSecret: process.env.AUTH_SECRET,
  }),
})

不安全的結構描述

使用 Dgraph 最快的方式是將不安全的結構描述套用至您的本機 Dgraph 執行個體,或者如果使用 Dgraph 雲端,您可以將結構描述貼到程式碼方塊中以進行更新。

⚠️

此方法不安全,不適用於生產環境,且不需要 jwtSecret

此結構描述適用於 Dgraph,並以我們主要的結構描述為基礎

範例

type Account {
  id: ID
  type: String
  provider: String @search(by: [hash])
  providerAccountId: String @search(by: [hash])
  refreshToken: String
  expires_at: Int64
  accessToken: String
  token_type: String
  refresh_token: String
  access_token: String
  scope: String
  id_token: String
  session_state: String
  user: User @hasInverse(field: "accounts")
}
type Session {
  id: ID
  expires: DateTime
  sessionToken: String @search(by: [hash])
  user: User @hasInverse(field: "sessions")
}
type User {
  id: ID
  name: String
  email: String @search(by: [hash])
  emailVerified: DateTime
  image: String
  accounts: [Account] @hasInverse(field: "user")
  sessions: [Session] @hasInverse(field: "user")
}
 
type VerificationToken {
  id: ID
  identifier: String @search(by: [hash])
  token: String @search(by: [hash])
  expires: DateTime
}

安全的結構描述

對於生產環境部署,您會想要限制對 next-auth 使用的類型的存取。Dgraph 中使用的主要存取控制形式是透過結構描述中類型旁的 @auth 指令。

範例

type Account
  @auth(
    delete: { rule: "{$nextAuth: { eq: true } }" }
    add: { rule: "{$nextAuth: { eq: true } }" }
    query: { rule: "{$nextAuth: { eq: true } }" }
    update: { rule: "{$nextAuth: { eq: true } }" }
  ) {
  id: ID
  type: String
  provider: String @search(by: [hash])
  providerAccountId: String @search(by: [hash])
  refreshToken: String
  expires_at: Int64
  accessToken: String
  token_type: String
  refresh_token: String
  access_token: String
  scope: String
  id_token: String
  session_state: String
  user: User @hasInverse(field: "accounts")
}
type Session
  @auth(
    delete: { rule: "{$nextAuth: { eq: true } }" }
    add: { rule: "{$nextAuth: { eq: true } }" }
    query: { rule: "{$nextAuth: { eq: true } }" }
    update: { rule: "{$nextAuth: { eq: true } }" }
  ) {
  id: ID
  expires: DateTime
  sessionToken: String @search(by: [hash])
  user: User @hasInverse(field: "sessions")
}
type User
  @auth(
    query: {
      or: [
        {
          rule: """
          query ($userId: String!) {queryUser(filter: { id: { eq: $userId } } ) {id}}
          """
        }
        { rule: "{$nextAuth: { eq: true } }" }
      ]
    }
    delete: { rule: "{$nextAuth: { eq: true } }" }
    add: { rule: "{$nextAuth: { eq: true } }" }
    update: {
      or: [
        {
          rule: """
          query ($userId: String!) {queryUser(filter: { id: { eq: $userId } } ) {id}}
          """
        }
        { rule: "{$nextAuth: { eq: true } }" }
      ]
    }
  ) {
  id: ID
  name: String
  email: String @search(by: [hash])
  emailVerified: DateTime
  image: String
  accounts: [Account] @hasInverse(field: "user")
  sessions: [Session] @hasInverse(field: "user")
}
 
type VerificationToken
  @auth(
    delete: { rule: "{$nextAuth: { eq: true } }" }
    add: { rule: "{$nextAuth: { eq: true } }" }
    query: { rule: "{$nextAuth: { eq: true } }" }
    update: { rule: "{$nextAuth: { eq: true } }" }
  ) {
  id: ID
  identifier: String @search(by: [hash])
  token: String @search(by: [hash])
  expires: DateTime
}
 
# Dgraph.Authorization {"VerificationKey":"<YOUR JWT SECRET HERE>","Header":"<YOUR AUTH HEADER HERE>","Namespace":"<YOUR CUSTOM NAMESPACE HERE>","Algo":"HS256"}

Dgraph.Authorization

為了保護您的 graphql 後端,請在結構描述底部定義 Dgraph.Authorization 物件,並將 authHeaderjwtSecret 值提供給 DgraphClient。

# Dgraph.Authorization {"VerificationKey":"<YOUR JWT SECRET HERE>","Header":"<YOUR AUTH HEADER HERE>","Namespace":"YOUR CUSTOM NAMESPACE HERE","Algo":"HS256"}

VerificationKey 和 jwtSecret

這是用來簽署 JWT 的金鑰。範例:process.env.SECRETprocess.env.APP_SECRET

Header 和 authHeader

Header 會告知 Dgraph 在傳入 Dgraph 伺服器的要求標頭中尋找 JWT 的位置。您必須在結構描述檔案的底部設定它。此標頭與您在例項化 DgraphClient 時提供的 authHeader 屬性相同。

nextAuth 密碼

$nextAuth 密碼是使用 jwtSecret 安全產生,並由 DgraphAdapter 注入,以便允許與 JWT DgraphClient 互動,以進行系統內匿名使用者要求 例如:登入、註冊。這允許與 next-auth 所需的所有驗證類型進行安全互動。您必須為安全結構描述中定義的每個類型的每個驗證規則指定它。

type VerificationRequest
  @auth(
    delete: { rule: "{$nextAuth: { eq: true } }" },
    add: { rule: "{$nextAuth: { eq: true } }" },
    query: { rule: "{$nextAuth: { eq: true } }" },
    update: { rule: "{$nextAuth: { eq: true } }" }
  ) {
}

JWT 工作階段和 @auth 指令

Dgraph 僅適用於 HS256 或 RS256 演算法。如果您想使用工作階段 JWT 來安全地與您的 Dgraph 資料庫互動,您必須自訂 next-auth encodedecode 函數,因為預設演算法為 HS512。如果您想實作RBAC 邏輯,您可以進一步使用角色自訂 JWT。

./auth.js
import NextAuth from "next-auth"
import * as jwt from "jsonwebtoken"
 
export const { handlers, auth, signIn, signOut } = NextAuth({
  session: {
    strategy: "jwt",
  },
  jwt: {
    secret: process.env.SECRET,
    encode: async ({ secret, token }) => {
      return jwt.sign({ ...token, userId: token.id }, secret, {
        algorithm: "HS256",
        expiresIn: 30 * 24 * 60 * 60, // 30 days
      })
    },
    decode: async ({ secret, token }) => {
      return jwt.verify(token, secret, { algorithms: ["HS256"] })
    },
  },
})

一旦您的 Dgraph.Authorization 在您的結構描述中定義,並且 JWT 設定已設定,這將允許您為結構描述的每個部分定義 @auth 規則

Auth.js © Balázs Orbán 和團隊 -2024