在博客项目中添加用户登录认证功能,并关联到 Google 和 Facebook 账号,可以使用 OAuth 2.0 协议。为了简化认证过程,我们可以利用 NextAuth.js,一个开箱即用的身份验证解决方案。我们将整合 NextAuth. Js,使其与 Google 和 Facebook 认证合作。

项目结构

我们将在现有项目结构中添加身份验证所需的文件和配置:

my-blog/
├── src/
│   ├── server.ts
│   ├── api.ts
│   ├── db.ts
│   ├── models.ts
│   ├── types.ts
│   └── components/
│       ├── PostEditor.tsx
│       ├── PostList.tsx
│       ├── CommentList.tsx
│       ├── CommentForm.tsx
│       ├── App.tsx
│       └── AuthButton.tsx
├── public/
│   ├── index.html
│   └── styles.css
├── Dockerfile
├── docker-compose.yml
├── tsconfig.json
├── package.json
├── bunfig.toml
└── vite.config.ts

1. 初始化 Next. Js 和 NextAuth

在项目根目录下,我们需要安装 Next. Js 和 NextAuth. Js 及有关依赖:

bun add next next-auth react react-dom @types/react @types/react-dom

2. 配置 NextAuth. Js

创建 pages/api/auth/[...nextauth].ts

首先,我们需要在 pages/api/auth/[...nextauth].ts 中配置 NextAuth. Js。这里,我们需要引入 Google 和 Facebook 认证提供程序。确保创建合适的环境变量以存储 OAuth 客户端 ID 和客户端密钥。

import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import FacebookProvider from 'next-auth/providers/facebook';
 
export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    FacebookProvider({
      clientId: process.env.FACEBOOK_CLIENT_ID!,
      clientSecret: process.env.FACEBOOK_CLIENT_SECRET!,
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
});

3. 配置环境变量

在项目根目录下创建 .env.local 文件,并添加相关的配置:

GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
FACEBOOK_CLIENT_ID=your-facebook-client-id
FACEBOOK_CLIENT_SECRET=your-facebook-client-secret
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-next-auth-secret

4. 更新 Next. Js 配置

创建 next.config.js 并更新 Vite 配置文件:

next.config.js

module.exports = {
  reactStrictMode: true,
};

vite.config.ts (增加 Next. Js 支持)

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
 
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
});

5. 前端集成

创建 src/components/AuthButton.tsx

// src/components/AuthButton.tsx
import React from 'react';
import { useSession, signIn, signOut } from 'next-auth/react';
 
const AuthButton: React.FC = () => {
  const { data: session } = useSession();
 
  if (session) {
    return (
      <div>
        Signed in as {session.user?.email} <br />
        <button onClick={() => signOut()}>Sign out</button>
      </div>
    );
  }
  return (
    <div>
      Not signed in <br />
      <button onClick={() => signIn('google')}>Sign in with Google</button>
      <button onClick={() => signIn('facebook')}>Sign in with Facebook</button>
    </div>
  );
};
 
export default AuthButton;

更新 src/components/App.tsx 以包含 AuthButton 组件

// src/components/App.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import PostList from './PostList';
import AuthButton from './AuthButton';
import { SessionProvider } from 'next-auth/react';
 
const App: React.FC = () => {
  return (
    <SessionProvider>
      <div className="app">
        <AuthButton />
        <PostList />
      </div>
    </SessionProvider>
  );
};
 
ReactDOM.render(<App />, document.getElementById('root'));

6. Docker 配置

更新 Dockerfile

Next. Js 和 NextAuth 的配置需要一些额外的步骤。我们需要分别打包前端和后端的代码。

# Use an official node image as the base image
FROM node:16 AS builder
 
# Set the working directory
WORKDIR /app
 
# Copy package.json and package-lock.json (if available)
COPY package.json .
COPY bun.lockb ./
 
# Install Bun
RUN npm install bun -g
 
# Copy the rest of the application
COPY . .
 
# Install dependencies
RUN bun install
 
# Build the Next.js application
RUN bun run build
 
# Start a new stage for the production build
FROM node:16 as production
 
WORKDIR /app
 
ENV NODE_ENV production
 
# Copy the build output from the previous stage
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/next.config.js ./next.config.js
 
# Expose the port the app runs on
EXPOSE 3000
 
# Run the Next.js server
CMD ["bun", "run", "src/server.ts"]

更新 docker-compose. Yml

确保在 docker-compose.yml 中定义环境变量:

version: '3.8'
 
services:
  db:
    image: postgres:13
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydatabase
    volumes:
      - pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"
 
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://user:password@db:5432/mydatabase
      GOOGLE_CLIENT_ID: your-google-client-id
      GOOGLE_CLIENT_SECRET: your-google-client-secret
      FACEBOOK_CLIENT_ID: your-facebook-client-id
      FACEBOOK_CLIENT_SECRET: your-facebook-client-secret
      NEXTAUTH_URL: http://localhost:3000
      NEXTAUTH_SECRET: your-next-auth-secret
    depends_on:
      - db
    volumes:
      - .:/app
      - /app/node_modules
 
volumes:
  pgdata:

7. 启动项目

首先确保环境变量已加载:

source .env.local

运行 Docker Compose:

docker-compose up --build

访问 http://localhost:3000 ,将可访问到一个包含 Google 和 Facebook 登录认证以及博客文章和评论功能的完整博客实例。

总结

通过本文,我们详细说明了如何在现有的博客实例中添加用户登录认证功能并关联到 Google 和 Facebook 账号。以下是已完成的主要任务:

  1. NextAuth. Js 配置:使用 NextAuth. Js 集成 Google 和 Facebook 登录认证。
  2. 前端集成:使用 React 实现用户登录和注销功能。
  3. Docker 配置:打包为 Docker 镜像,并在 Docker Compose 中定义环境变量。

希望这个示例能帮助你更好地理解如何结合这些技术扩展应用的功能。如果有任何问题或需要进一步的帮助,请随时提问!