小明: 大家好,我正在构建一个需要统一身份认证的平台,想听听大家有什么建议?
小红: 统一身份认证对于提高用户体验非常重要。你打算怎么实现呢?
小明: 我考虑使用OAuth 2.0作为认证协议,前端通过调用后端API完成认证流程。
小华: OAuth 2.0是个不错的选择。你能展示一下前端的具体实现吗?
小明: 当然可以。首先我们需要一个简单的HTML页面用于用户登录:
<html>
<head>
<title>登录页面</title>
</head>
<body>
<button onclick="login()">点击登录</button>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
function login() {
axios.get('/auth/oauth2/authorize', {
params: {
response_type: 'code',
client_id: 'client_id',
redirect_uri: 'http://example.com/callback',
scope: 'read write'
}
}).then(response => {
window.location.href = response.data.authorization_url;
});
}
</script>
</body>
</html>
小红: 这样用户就可以被重定向到认证服务器进行认证了。接下来呢?
小明: 认证成功后,用户会被重定向回我们的回调URL。此时我们可以通过获取授权码来交换访问令牌:
<script>
function handleCallback(code) {
axios.post('/auth/oauth2/token', {
grant_type: 'authorization_code',
code: code,
redirect_uri: 'http://example.com/callback',
client_id: 'client_id',
client_secret: 'client_secret'
}).then(response => {
// 获取到access_token后,我们可以将其存储在localStorage或sessionStorage中
localStorage.setItem('access_token', response.data.access_token);
});
}
// 在回调页面中调用handleCallback函数
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
if (code) {
handleCallback(code);
}
</script>
小华: 看起来很不错!那么,当用户需要访问受保护资源时,我们应该如何处理呢?
小明: 我们可以在请求头中包含access_token,这样后端就可以验证用户的合法性了:
<script>
function fetchProtectedResource() {
axios.get('/protected/resource', {
headers: {
Authorization: `Bearer ${localStorage.getItem('access_token')}`
}
}).then(response => {
console.log(response.data);
});
}
</script>
小红: 这样就完成了整个流程。感谢分享你的实现细节!