导航菜单

在Vue项目中使用Appwrite实现GitHub登录

前言

在现代 Web 应用开发中,社交媒体登录已经成为一种标配功能。本文将介绍如何利用 Appwrite 云服务在 Vue 项目中快速实现 GitHub 登录功能。Appwrite 是一个开源的后端即服务(BaaS)平台,提供了丰富的 API 和 SDK,可以帮助开发者轻松实现用户认证、数据库、存储等功能。

准备工作

1. GitHub OAuth 应用配置

  1. 登录 GitHub,进入 Settings > Developer settings > OAuth Apps
  2. 点击”New OAuth App”创建新应用
  3. 填写应用信息:
  4. 创建完成后,记录下 Client ID 和 Client Secret

2. Appwrite 平台配置

  1. 注册并登录 Appwrite 控制台
  2. 创建新项目
  3. 在项目设置中添加平台:
    • 选择 Web 平台
    • 添加项目域名(开发环境使用 localhost)
  4. 在 Authentication 设置中:
    • 启用 GitHub OAuth 提供商
    • 配置 GitHub Client ID 和 Client Secret

3. Vue 项目环境准备

# 创建Vue项目(如果是新项目)
npm create vue@latest my-vue-app

# 安装Appwrite SDK
npm install appwrite

# 安装Vue Router(如果需要)
npm install vue-router

实现步骤

1. 配置 Appwrite 服务

创建src/services/appwrite.js文件:

import { Client, Account } from 'appwrite';

// 初始化Appwrite客户端
const client = new Client()
    .setEndpoint('你的Appwrite API端点') // 例如:https://cloud.appwrite.io/v1
    .setProject('你的项目ID');

// 导出Account实例用于认证操作
export const account = new Account(client);

2. 创建登录组件

创建src/components/GitHubLogin.vue组件:

<template>
    <div class="github-login">
        <button @click="handleLogin" :disabled="loading">
            {{ loading ? '登录中...' : '使用GitHub登录' }}
        </button>
    </div>
</template>

<script setup>
import { ref } from 'vue';
import { account } from '../services/appwrite';
import { useRouter } from 'vue-router';

const router = useRouter();
const loading = ref(false);

const handleLogin = async () => {
    try {
        loading.value = true;
        // 创建GitHub OAuth会话
        await account.createOAuth2Session(
            'github',
            'http://localhost:3000/auth/callback', // 成功回调地址
            'http://localhost:3000/auth/error' // 失败回调地址
        );
    } catch (error) {
        console.error('GitHub登录失败:', error);
        loading.value = false;
    }
};
</script>

<style scoped>
.github-login button {
    padding: 10px 20px;
    background-color: #24292e;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 16px;
}

.github-login button:disabled {
    background-color: #6e7681;
    cursor: not-allowed;
}
</style>

3. 创建回调处理组件

创建src/components/AuthCallback.vue组件:

<template>
    <div class="auth-callback">
        <p v-if="loading">正在处理登录...</p>
        <p v-if="error">{{ error }}</p>
    </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { account } from '../services/appwrite';
import { useRouter } from 'vue-router';

const router = useRouter();
const loading = ref(true);
const error = ref('');

onMounted(async () => {
    try {
        // 获取当前会话信息
        const session = await account.getSession('current');

        // 获取用户信息
        const user = await account.get();

        // 存储用户信息到本地
        localStorage.setItem('user', JSON.stringify(user));

        // 登录成功,跳转到首页
        router.push('/');
    } catch (err) {
        error.value = '认证失败:' + err.message;
    } finally {
        loading.value = false;
    }
});
</script>

4. 配置路由

src/router/index.js中添加路由配置:

import { createRouter, createWebHistory } from 'vue-router';
import GitHubLogin from '../components/GitHubLogin.vue';
import AuthCallback from '../components/AuthCallback.vue';

const routes = [
    {
        path: '/login',
        component: GitHubLogin,
    },
    {
        path: '/auth/callback',
        component: AuthCallback,
    },
    {
        path: '/auth/error',
        component: () => import('../components/AuthError.vue'),
    },
];

const router = createRouter({
    history: createWebHistory(),
    routes,
});

export default router;

使用和测试

  1. 启动 Vue 开发服务器:
npm run dev
  1. 访问登录页面(如:http://localhost:3000/login)

  2. 点击”使用 GitHub 登录”按钮

  3. 授权 GitHub 访问

  4. 等待回调处理完成,自动跳转到首页

安全性考虑

  1. 环境变量:将 Appwrite 配置信息存储在.env文件中:
VITE_APPWRITE_ENDPOINT=你的Appwrite API端点
VITE_APPWRITE_PROJECT_ID=你的项目ID
  1. 会话管理
  • 定期检查会话状态
  • 实现登出功能
  • 处理会话过期情况
// 检查会话状态
const checkSession = async () => {
    try {
        await account.getSession('current');
        return true;
    } catch {
        return false;
    }
};

// 登出功能
const logout = async () => {
    try {
        await account.deleteSession('current');
        localStorage.removeItem('user');
        router.push('/login');
    } catch (error) {
        console.error('登出失败:', error);
    }
};

常见问题解决

  1. 跨域问题:确保 Appwrite 平台配置中添加了正确的域名

  2. 回调 URL 错误:检查 GitHub OAuth 应用和 Appwrite 平台中的回调 URL 配置是否一致

  3. Safari ITP 影响登录:Safari 的智能防跨站追踪(ITP)功能可能导致登录失效

  • 问题原理

    • Safari 的 ITP 功能会限制第三方 Cookie 的访问
    • Appwrite 作为第三方服务需要在浏览器中存储认证 Cookie
    • ITP 会阻止网站读取这些第三方 Cookie,导致会话状态丢失
  • 解决方案

    1. 提示用户在 Safari 中临时禁用”防止跨站追踪”功能
    2. 使用自定义域名将 Appwrite 服务部署为同域服务
    3. 实现备用的本地存储认证方案
  1. 会话状态异常:实现错误重试机制
const retryOperation = async (operation, maxAttempts = 3) => {
    for (let attempt = 1; attempt <= maxAttempts; attempt++) {
        try {
            return await operation();
        } catch (error) {
            if (attempt === maxAttempts) throw error;
            await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
        }
    }
};

总结

通过 Appwrite 云服务实现 GitHub 登录具有以下优势:

  1. 快速集成:无需自建后端服务
  2. 安全可靠:使用标准 OAuth2.0 协议
  3. 易于维护:Appwrite 提供完整的管理界面
  4. 可扩展性:支持添加其他社交登录方式

本文介绍的实现方案适用于大多数中小型 Vue 项目。对于大型项目,可能需要考虑更复杂的认证流程和用户权限管理。

参考资源

搜索