JavaScript (Node.js) OAuth 客户端库概述
OAuth(开放授权)是一种开放授权协议,允许第三方在无需提供用户名和密码的情况下,获得对用户资源的有限访问权限。在 Node.js 生态系统中,有多个成熟的库实现了 OAuth 2.0 和 OAuth 1.0a。在本文中,我们将介绍三种最流行的解决方案:simple-oauth2、oauth4webapi 和 Passport.js 及其策略。您将了解如何选择合适的工具以及如何将其集成到您的项目中。
1. simple-oauth2 — 通用 OAuth 2.0 客户端
simple-oauth2 是一个轻量级库,提供了用于处理 OAuth 2.0 的简洁 API。它支持所有主要的授权类型(授权码、客户端凭证、密码、刷新令牌)。非常适合需要完全控制流程的服务器端应用程序。
安装
npm install simple-oauth2示例:通过 GitHub 授权
const express = require('express');const simpleOAuth2 = require('simple-oauth2');const app = express();
const config = { client: { id: '您的_CLIENT_ID', secret: '您的_CLIENT_SECRET' }, auth: { tokenHost: 'https://github.com', tokenPath: '/login/oauth/access_token', authorizePath: '/login/oauth/authorize' }};
const oauth2 = new simpleOAuth2.ClientCredentials(config);
// 开始授权的路由app.get('/auth/github', (req, res) => { const authorizationUri = oauth2.authorizeURL({ redirect_uri: 'http://localhost:3000/callback', scope: 'user:email' }); res.redirect(authorizationUri);});
// 回调路由app.get('/callback', async (req, res) => { const { code } = req.query; try { const result = await oauth2.getToken({ code, redirect_uri: 'http://localhost:3000/callback' }); const accessToken = oauth2.createToken(result); console.log('Access Token:', accessToken.token.access_token); res.send('授权成功!'); } catch (error) { console.error('获取令牌时出错', error); res.status(500).send('授权错误'); }});
app.listen(3000, () => console.log('服务器已启动,端口 3000'));2. oauth4webapi — 现代标准
oauth4webapi 是 OAuth 2.0 和 OpenID Connect 最新规范的实现。该库没有外部依赖,支持 PKCE(代码交换证明密钥)和 JWK(JSON Web 密钥)的使用。推荐用于注重安全性和标准合规性的新项目。
安装
npm install oauth4webapi示例:使用 PKCE 的授权
const express = require('express');const { AuthorizationServer, Client, generateCodeVerifier, generateCodeChallenge } = require('oauth4webapi');const app = express();
// 授权服务器配置(Google)const issuer = new URL('https://accounts.google.com');const server = new AuthorizationServer(issuer);const client = new Client({ client_id: '您的_CLIENT_ID', client_secret: '您的_CLIENT_SECRET', redirect_uris: ['http://localhost:3000/callback']});
app.get('/auth/google', async (req, res) => { const codeVerifier = generateCodeVerifier(); const codeChallenge = await generateCodeChallenge(codeVerifier); // 将 codeVerifier 保存在会话中 req.session.codeVerifier = codeVerifier;
const authorizationUrl = new URL(server.authorization_endpoint); authorizationUrl.searchParams.set('client_id', client.client_id); authorizationUrl.searchParams.set('redirect_uri', client.redirect_uris[0]); authorizationUrl.searchParams.set('response_type', 'code'); authorizationUrl.searchParams.set('scope', 'openid profile email'); auth