Node.js 如何实现 GitHub 登录(OAuth 2.0)

在 Node.js 中实现 GitHub 登录功能,通常需要使用 OAuth 2.0 协议。GitHub 提供了 OAuth 认证机制,用户可以通过 GitHub 登录授权应用访问其数据。以下是实现 GitHub 登录的步骤。

我们将使用 passport 中间件和 passport-github2 策略来简化 OAuth 认证流程。

1. 安装所需的 npm 包

首先,创建一个新的 Node.js 项目并安装必需的依赖:

csharp 复制代码
bash
复制编辑
npm init -y
npm install express passport passport-github2 express-session dotenv
  • express: 用于构建 web 应用。
  • passport: 用于认证的中间件。
  • passport-github2: GitHub 的 OAuth 认证策略。
  • express-session: 用于管理会话。
  • dotenv: 用于管理环境变量。

2. 配置 GitHub OAuth 应用

在 GitHub 上创建 OAuth 应用并获取 Client IDClient Secret,步骤如下:

  1. 访问 GitHub OAuth Applications

  2. 点击 "New OAuth App" 按钮。

  3. 填写以下信息:

    • Application Name:应用名称(例如:"MyApp")。
    • Homepage URL :应用主页的 URL(例如:http://localhost:3000)。
    • Authorization callback URL :回调 URL(例如:http://localhost:3000/auth/github/callback)。
  4. 点击 Register Application

你会获得 Client IDClient Secret,这些需要在代码中使用。

3. 配置 .env 文件

在项目根目录下创建一个 .env 文件,存储 GitHub 的 Client IDClient Secret

ini 复制代码
env
复制编辑
GITHUB_CLIENT_ID=your-client-id
GITHUB_CLIENT_SECRET=your-client-secret
GITHUB_CALLBACK_URL=http://localhost:3000/auth/github/callback
SESSION_SECRET=your-session-secret

4. 创建 app.js 文件并实现 OAuth 登录

创建 app.js 文件并编写以下代码:

javascript 复制代码
javascript
复制编辑
const express = require('express');
const passport = require('passport');
const session = require('express-session');
const dotenv = require('dotenv');
const GitHubStrategy = require('passport-github2').Strategy;

dotenv.config();

const app = express();
const port = 3000;

// 设置会话中间件
app.use(session({
    secret: process.env.SESSION_SECRET,
    resave: false,
    saveUninitialized: true
}));

// 初始化 Passport
app.use(passport.initialize());
app.use(passport.session());

// 配置 Passport 使用 GitHub OAuth 2.0 策略
passport.use(new GitHubStrategy({
    clientID: process.env.GITHUB_CLIENT_ID,
    clientSecret: process.env.GITHUB_CLIENT_SECRET,
    callbackURL: process.env.GITHUB_CALLBACK_URL
}, function(accessToken, refreshToken, profile, done) {
    // 在此处可以将 GitHub 用户信息存储到数据库
    return done(null, profile);
}));

// 序列化用户到 session 中
passport.serializeUser(function(user, done) {
    done(null, user);
});

// 反序列化用户
passport.deserializeUser(function(user, done) {
    done(null, user);
});

// 路由:跳转到 GitHub 登录页面
app.get('/auth/github', (req, res) => {
    passport.authenticate('github', { scope: ['user:email'] })(req, res);
});

// 路由:GitHub 登录回调
app.get('/auth/github/callback', (req, res) => {
    passport.authenticate('github', { failureRedirect: '/' })(req, res, function() {
        res.redirect('/profile');
    });
});

// 路由:用户个人资料页面
app.get('/profile', (req, res) => {
    if (!req.isAuthenticated()) {
        return res.redirect('/');
    }
    res.json(req.user);  // 返回用户信息
});

// 路由:退出登录
app.get('/logout', (req, res) => {
    req.logout(function(err) {
        res.redirect('/');
    });
});

// 路由:首页
app.get('/', (req, res) => {
    if (req.isAuthenticated()) {
        return res.redirect('/profile');
    }
    res.send('<a href="/auth/github">Login with GitHub</a>');
});

// 启动服务器
app.listen(port, () => {
    console.log(`Server is running at http://localhost:${port}`);
});

代码解释:

  1. GitHub OAuth 配置 :通过 passport-github2 策略配置 GitHub OAuth 认证,使用 Client IDClient Secret 进行认证。
  2. /auth/github:此路由用于触发 GitHub 登录流程,用户点击链接后,会被重定向到 GitHub 登录页面。
  3. /auth/github/callback :GitHub 会回调此路由,将认证信息传递给应用。如果认证成功,用户信息将会存储在 req.user 中,并跳转到 /profile 页面。
  4. /profile:如果用户已经登录,将显示用户的 GitHub 个人资料。
  5. /logout:用于用户退出登录。
  6. passport.serializeUserpassport.deserializeUser:这两个方法将用户信息存储到会话中。

5. 启动应用并测试

  1. 启动 Node.js 应用:

    复制代码
    bash
    复制编辑
    node app.js
  2. 打开浏览器,访问 http://localhost:3000

  3. 点击 Login with GitHub,GitHub 将提示你授权应用。

  4. 完成授权后,你将被重定向到 /profile 页面,显示你的 GitHub 用户信息。

6. 处理认证失败和错误(可选)

你可能需要在认证失败时提供合适的反馈,可以在 passport.authenticate 中设置 failureRedirect

javascript 复制代码
javascript
复制编辑
app.get('/auth/github/callback', (req, res) => {
    passport.authenticate('github', { failureRedirect: '/' })(req, res, function() {
        res.redirect('/profile');
    });
});

如果认证失败,用户将被重定向到首页。

7. 保护路由(可选)

你可以通过 req.isAuthenticated() 来检查用户是否已认证,如果没有认证,则重定向到登录页面。

javascript 复制代码
javascript
复制编辑
app.get('/profile', (req, res) => {
    if (!req.isAuthenticated()) {
        return res.redirect('/');
    }
    res.json(req.user);  // 返回用户信息
});

总结

通过上述步骤,你已经成功地在 Node.js 中实现了 GitHub 登录。使用 Passportpassport-github2 策略简化了 OAuth 认证流程。你可以根据需要扩展功能,比如存储用户数据、处理登录状态等。

相关推荐
一起学开源9 分钟前
一文读懂 ReAct 范式:让 AI Agent 真正学会“思考+行动“
java·javascript·react.js·ecmascript·react·alibaba·智能体开发
游九尘2 小时前
JavaScript 实现三段式版本号对比函数(app升级用)
javascript·uni-app
zhiSiBuYu05172 小时前
Claude-Code 新手极速上手指南
javascript·node.js
罗超驿3 小时前
18.Web API 实战:元素与表单属性的获取和修改
开发语言·前端·javascript
山河已无恙3 小时前
BPF-eBPF 开发路线二:libbpf、CO-RE 与 libbpf-bootstrap认知
javascript·bootstrap·php
ZengLiangYi4 小时前
React Query + REST API 最佳实践
javascript·后端·react.js
ZengLiangYi4 小时前
Fastify 加 Electron:把 Web 服务嵌进桌面应用
前端·javascript·后端
胡萝卜术5 小时前
从零搭建生成式AI项目:OpenAI + Node.js 环境配置与密钥安全实践
前端·javascript·面试
柒和远方5 小时前
每日一学V012: 从 Python 到 Node.js:一个 AI Native 开发者的 JavaScript 调用 LLM 实战
javascript·node.js·api
STDD5 小时前
Farming Simulator 25(模拟农场 25) Linux 专服搭建完全指南
linux·运维·javascript