介紹
身份驗證是任何軟體、應用程式或系統中非常重要的組件,它透過限制應用程式的某些區域來提供額外的安全層。例如,一個包含重要資訊的儀表板,除非使用者已通過身份驗證,否則無法訪問。當然,我們可以實作使用者、電子郵件和密碼的方式,讓使用者創建帳號,然後使用者接收到一封郵件以驗證電子郵件,只有在這之後,使用者才能訪問經過身份驗證的內容。這個流程仍然相當流行,但對於許多使用者而言,這些額外的步驟有些繁瑣,因為使用像是 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://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