单点登录(Single Sign-On, SSO)是一种身份验证机制,允许用户使用一组凭据登录多个相关但独立的系统。在不同域名之间实现单点登录,通常涉及到跨域认证和会话管理。
原因:浏览器的同源策略限制了不同域名之间的Cookie共享。
解决方法:
原因:不同服务器之间的会话信息无法同步。
解决方法:
原因:跨域认证可能带来安全风险,如CSRF攻击。
解决方法:
以下是一个基于JWT的单点登录示例:
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
app.use(express.json());
const SECRET_KEY = 'your-secret-key';
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 验证用户名和密码
if (username === 'admin' && password === 'password') {
const token = jwt.sign({ username }, SECRET_KEY, { expiresIn: '1h' });
res.json({ token });
} else {
res.status(401).json({ message: 'Invalid credentials' });
}
});
app.get('/protected', verifyToken, (req, res) => {
jwt.verify(req.token, SECRET_KEY, (err, authData) => {
if (err) {
res.status(403).json({ message: 'Forbidden' });
} else {
res.json({ message: `Hello, ${authData.username}!` });
}
});
});
function verifyToken(req, res, next) {
const bearerHeader = req.headers['authorization'];
if (typeof bearerHeader !== 'undefined') {
const bearerToken = bearerHeader.split(' ')[1];
req.token = bearerToken;
next();
} else {
res.status(403).json({ message: 'No token provided' });
}
}
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
async function login() {
const response = await fetch('http://localhost:3000/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ username: 'admin', password: 'password' })
});
const data = await response.json();
localStorage.setItem('token', data.token);
}
async function accessProtectedResource() {
const token = localStorage.getItem('token');
const response = await fetch('http://localhost:3000/protected', {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`
}
});
const data = await response.json();
console.log(data.message);
}
通过以上方法,可以实现不同域名之间的单点登录,并解决常见的跨域和安全问题。
领取专属 10元无门槛券
手把手带您无忧上云