使用OAuth 2.0 + PKCE实现前端安全授权,首先生成code verifier和challenge,再重定向至第三方登录页,用户授权后回调获取code,最后用code和verifier换取access token并调用API,建议由后端完成token交换以提升安全性。

JavaScript 实现 OAuth 认证流程通常用于前端应用(如单页应用 SPA)与第三方服务(如 Google、GitHub、Facebook)进行安全授权。由于 JavaScript 运行在浏览器端,不能安全存储密钥,因此推荐使用 OAuth 2.0 的授权码流程 + PKCE(Proof Key for Code Exchange),这是目前最安全且广泛支持的方式。
PKCE 是标准授权码流程的增强版本,防止授权码被中间人劫持。适用于无法安全保存客户端密钥的场景,比如纯前端应用。
主要步骤如下:
步骤 1:生成 Code Verifier 和 Challenge
立即学习“Java免费学习笔记(深入)”;
function generateCodeVerifier() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return btoa(String.fromCharCode(...array))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
async function generateCodeChallenge(verifier) {
const data = new TextEncoder().encode(verifier);
const digest = await crypto.subtle.digest('SHA-256', data);
return btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
步骤 2:跳转到 GitHub 授权页面
async function redirectToAuth() {
const clientId = 'your_client_id';
const redirectUri = 'https://yourapp.com/callback';
const scope = 'user:email';
const codeVerifier = generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
// 存储 codeVerifier,后续换 token 时需要
sessionStorage.setItem('code_verifier', codeVerifier);
const authUrl = new URL('https://github.com/login/oauth/authorize');
authUrl.searchParams.append('client_id', clientId);
authUrl.searchParams.append('redirect_uri', redirectUri);
authUrl.searchParams.append('scope', scope);
authUrl.searchParams.append('response_type', 'code');
authUrl.searchParams.append('code_challenge', codeChallenge);
authUrl.searchParams.append('code_challenge_method', 'S256');
window.location.href = authUrl.toString();
}
步骤 3:回调页处理授权码并请求 Token
在 https://yourapp.com/callback 页面中提取 code,并用 code + code_verifier 换取 token:
async function handleCallback() {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
if (!code) return;
const codeVerifier = sessionStorage.getItem('code_verifier');
if (!codeVerifier) return;
const tokenUrl = 'https://github.com/login/oauth/access_token';
const params = new URLSearchParams();
params.append('client_id', 'your_client_id');
params.append('code', code);
params.append('code_verifier', codeVerifier);
params.append('redirect_uri', 'https://yourapp.com/callback');
const response = await fetch(tokenUrl, {
method: 'POST',
headers: { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' },
body: params
});
const data = await response.json();
if (data.access_token) {
sessionStorage.setItem('access_token', data.access_token);
window.location.href = '/'; // 回主页面
}
}
拿到 token 后,可在请求头中携带它调用第三方 API:
fetch('https://api.github.com/user', {
headers: { 'Authorization': `Bearer ${access_token}` }
})
.then(res => res.json())
.then(user => console.log(user));
以上就是JavaScript OAuth认证流程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号