介紹

身份驗證是任何軟體、應用程式或系統中非常重要的組件,它透過限制應用程式的某些區域來提供額外的安全層。例如,一個包含重要資訊的儀表板,除非使用者已通過身份驗證,否則無法訪問。當然,我們可以實作使用者、電子郵件和密碼的方式,讓使用者創建帳號,然後使用者接收到一封郵件以驗證電子郵件,只有在這之後,使用者才能訪問經過身份驗證的內容。這個流程仍然相當流行,但對於許多使用者而言,這些額外的步驟有些繁瑣,因為使用像是 Google、Microsoft、Apple 等提供者進行身份驗證要簡單得多,幾次點擊就能完成身份驗證,甚至不需要離開當前螢幕。這種輕鬆的訪問方式在構建應用程式時絕對應該考慮,以便使用者可以選擇他們想要的方式。

在本文中,我們將使用 Clerk 與 React.js 和 Next.js,不幸的是,Clerk 尚未完全支援 Vue.js 或 Nuxt.js 應用程式,在 Clerk 的官方文檔中,我們可以找到關於 Vue.js 的提及,但僅能透過 SDK 使用。

使用 React.js 的 Clerk

第一步是登錄 Clerk 的網站,選擇希望在應用程式中提供的提供者。在免費層中,您可以選擇最多 3 個提供者,如果希望擁有更多提供者,則需要升級帳戶。

圖片描述

將其添加到 React.js 應用程式的第二步相當簡單。首先,我們需要安裝 clerk 套件:

npm install @clerk/clerk-react

接下來,我們需要設置環境變數,首先檢查您是否已擁有 env.local 文件以將金鑰添加到該文件中,如果您沒有此文件,您可以創建一個並將 clerk 可發布金鑰添加如下:

VITE_CLERK_PUBLISHABLE_KEY=pk_test_************************

下一步是導入可發布金鑰,我們可以通過轉到 main.ts 文件來導入,您還可以添加一個 if 檢查以避免 TypeScript 錯誤。

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'

// 導入您的可發布金鑰
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY

if (!PUBLISHABLE_KEY) {
  throw new Error('缺少可發布金鑰')
}

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

現在我們必須在 main.ts 文件中添加 <ClerkProvider />,並將整個應用包裝在 <ClerkProvider /> 中,如下所示,並將可發布金鑰附加給它:

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import { ClerkProvider } from '@clerk/clerk-react'

// 導入您的可發布金鑰
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY

if (!PUBLISHABLE_KEY) {
  throw new Error('缺少可發布金鑰')
}

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <ClerkProvider publishableKey={PUBLISHABLE_KEY} afterSignOutUrl="/">
      <App />
    </ClerkProvider>
  </React.StrictMode>,
)

最後一步是在標頭組件中添加 Clerk 組件,以處理身份驗證步驟,例如登錄、登出,以及我們在過程中選擇的像 Google、Microsoft、Github、Apple 等的驗證按鈕。您可以根據自己的需求組織 Header 組件,只需導入 Clerk 的組件,它就應該能正常工作。

import { SignedIn, SignedOut, SignInButton, UserButton } from '@clerk/clerk-react'

export function Header() {
  return (
    <header>
      <SignedOut>
        <SignInButton />
      </SignedOut>
      <SignedIn>
        <UserButton />
      </SignedIn>
    </header>
  )
}

並且不要忘了添加套件 React-Router-Dom,以便在使用者驗證後導航到任何頁面。

使用 Next.js 的 Clerk

將 Clerk 添加到 Next.js 應用程式的步驟幾乎是相同的,只是有一些變更,讓我們看看如何做到這一點。

首先,使用您的帳戶登錄 Clerk 的網站,選擇提供者並添加可發布金鑰,請記住 Next.js 對其環境變數有不同的命名慣例。

使用 Next.js 需要在環境文件中添加 2 個值,一個是為 Next.js 添加的可發布金鑰,另一個是密鑰:

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_************************
CLERK_SECRET_KEY=sk_test_************************

下一步是添加中介軟體,攔截未經身份驗證的使用者路徑,您可以在根目錄中創建一個名為 middleware.ts 的文件。以下是進行路由驗證並強制身份驗證的代碼,使用 Clerk 提供的 auth() 和 protect() 函數:

import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'

const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/forum(.*)'])

export default clerkMiddleware((auth, req) => {
  if (isProtectedRoute(req)) auth().protect()
})

export const config = {
  matcher: [
    // 跳過 Next.js 的內部和所有靜態文件,除非在搜索參數中找到
    '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
    // 始終對 API 路徑執行
    '/(api|trpc)(.*)',
  ],
}

現在我們將在 main layout.tsx 文件中添加 <ClerkProvider />,包裝整個應用以使 Clerk 在全局可用。

import { ClerkProvider, SignInButton, SignedIn, SignedOut, UserButton } from '@clerk/nextjs'
import './globals.css'
import Header from '@/components/Header';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <ClerkProvider>
      <html lang="en">
        <body>
          <Header />
          <main>{children}</main>
        </body>
      </html>
    </ClerkProvider>
  )
}

現在我們添加 Header 組件並使用 Clerk 組件:

import { SignedIn, SignedOut, SignInButton, UserButton } from '@clerk/nextjs';

export function Header() {
  return (
    <header>
      <SignedOut>
        <SignInButton />
      </SignedOut>
      <SignedIn>
        <UserButton />
      </SignedIn>
    </header>
  )
}

使用 Vue 的 Clerk

要將 Clerk 添加到 Vue.js 應用程式,我們需要使用 Clerk 的 SDK。這個過程很簡單,這是使用 Clerk 的其中一個好處,它的簡單性。

使用以下命令將 SDK 安裝到您的項目中:

npm install vue-clerk

將可發布金鑰添加到您的項目中,與 Next.js 不同,對於 Vue.js 和 React.js,只有一個金鑰需要添加到 .env.local 文件中:

VITE_CLERK_PUBLISHABLE_KEY=pk_test_************************

然後在 src 文件夾中的 main.ts 文件中導入 Clerk 可發布金鑰:

import { createApp } from 'vue'
import App from './App.vue'

const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY

if (!PUBLISHABLE_KEY) {
  throw new Error('缺少可發布金鑰')
}

const app = createApp(App)
app.mount('#app')

從 vue-clerk 添加 clerkPlugin

import { createApp } from 'vue'
import App from './App.vue'
import { clerkPlugin } from 'vue-clerk'

const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY

if (!PUBLISHABLE_KEY) {
  throw new Error('缺少可發布金鑰')
}

const app = createApp(App)
app.use(clerkPlugin, {
  publishableKey: PUBLISHABLE_KEY
})
app.mount('#app')

現在創建您的標頭組件並使用 Clerk 的預建組件:

<script setup>
     import { SignedIn, SignedOut, SignInButton, UserButton } from 'vue-clerk'
</script>

<template>
  <SignedOut>
    <SignInButton />
  </SignedOut>
  <SignedIn>
    <UserButton />
  </SignedIn>
</template>

並使用 vue-router 在使用者完成身份驗證後導航到已驗證的頁面。

使用 Nuxt.js 的 Clerk

Nuxt.js 應用程式需要使用 vue-clerk 並執行一些附加步驟,以使 Clerk 能夠與 Nuxt.js 架構正常運行。這是一個與 Next.js 類似的不同過程,因為這兩種技術有類似的目的。

在 nuxt.config.ts 中,我們將模組 vue-clerk/nuxt 添加到模組數組中,通過這樣做,所有組件和組合將被自動導入

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['vue-clerk/nuxt'],
  clerk: {
    appearance: {},
  }
})

然後在您的環境文件中添加環境變數:

NUXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_publishable_key
NUXT_CLERK_SECRET_KEY=your_secret_key

環境變數將在 nuxt.config.ts 文件中使用 runtimeConfig 加載,並且需注意命名慣例,必須符合 NUXT_PUBLIC_YOUR_ENV 和 runtimeConfig 對象的要求,否則我們可能會在開發和構建環境之間遇到不一致。

export default defineNuxtConfig({
  modules: ['vue-clerk/nuxt'],
  clerk: {
    appearance: {},
  },
  runtimeConfig: {
    public: {
      clerkPublishableKey: process.env.CLERK_PUBLISHABLE_KEY,
    },
  }
});

接下來的步驟是使用 Clerk 組件,例如在 Header 組件中:

<script lang="ts" setup>
// 您不需要從 Clerk 導入任何東西
</script>

<template>
  <div>
    <SignIn />
  </div>
</template>

我們還必須保護需要身份驗證的路由,如果使用者未經授權,他將被重定向到主頁或我們想要的任何地方。

// middleware/auth.ts
import { defineNuxtRouteMiddleware, navigateTo } from '#app';
import { useClerk } from '@clerk/clerk-vue';

export default defineNuxtRouteMiddleware(() => {
  const clerk = useClerk();

  if (!clerk.user.value) {
    return navigateTo('/sign-in');
  }
});

接下來的步驟是添加類型以確保 Clerk 在 TypeScript 中正常運行。由於我們使用的是 Vue.js 和 Nuxt.js 的 SDK,無需安裝 @clerk/types 套件,因為 SDK 包含自己的類型定義。您可以閱讀庫中的文件以確定確切的類型。

import { UserResource } from '@clerk/types';

// 使用 Clerk 的使用者類型的示例函數
function getUserName(user: UserResource) {
  Return { 
user.firstName || 'Guest', 
user.emailAddresses; 
  }
}

最後需要啟用 TypeScript 模組以構建應用程序,以便其能夠在生產環境中部署。

export default defineNuxtConfig({
  modules: ['vue-clerk/nuxt'],
  clerk: {
    appearance: {},
  },
  runtimeConfig: {
    public: {
      clerkPublishableKey: process.env.CLERK_PUBLISHABLE_KEY,
    },
  },
  buildModules: ['@nuxt/typescript-build'], // 啟用 TypeScript
});

結論

使用 Clerk 進行身份驗證非常簡單且輕鬆,現在您可以將其添加到您的項目中,為您的使用者提供另一個選擇,這將有助於提升使用者體驗。

參考資料

https://clerk.com/docs/quickstarts/react

https://clerk.com/docs/quickstarts/nextjs

https://vue-clerk.vercel.app/

https://clerk.com/docs/references/react/use-clerk

https://github.com/wobsoriano/nuxt-clerk-template/tree/main

https://www.vue-clerk.com/guides/nuxt

https://www.npmjs.com/package/@clerk/types

https://github.com/clerk/javascript/blob/e483037f61b4cfa8a04be27971f3b09eb88c84ac/packages/types/src/user.ts#L52


原文出處:https://dev.to/hramonpereira/how-to-manage-user-authentication-in-reactjs-nextjs-vuejs-and-nuxtjs-using-clerk-136l


共有 0 則留言