首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

不同域名单点登录

基础概念

单点登录(Single Sign-On, SSO)是一种身份验证机制,允许用户使用一组凭据登录多个相关但独立的系统。在不同域名之间实现单点登录,通常涉及到跨域认证和会话管理。

相关优势

  1. 用户体验提升:用户只需记住一组凭据,减少了重复登录的麻烦。
  2. 安全性增强:集中管理用户身份验证,减少了密码泄露的风险。
  3. 管理效率提高:简化了用户管理和权限分配的过程。

类型

  1. 基于Cookie的单点登录:通过在不同域名之间共享Cookie来实现。
  2. 基于OAuth的单点登录:使用OAuth协议进行第三方认证。
  3. 基于SAML的单点登录:使用安全断言标记语言(SAML)进行跨域认证。

应用场景

  1. 企业内部系统:多个子系统需要统一认证。
  2. 第三方应用集成:多个应用需要共享用户身份信息。
  3. 云服务提供商:多个云服务实例需要统一用户管理。

遇到的问题及解决方法

问题1:跨域Cookie无法共享

原因:浏览器的同源策略限制了不同域名之间的Cookie共享。

解决方法

  • 使用子域名:将所有系统部署在同一个主域名下,通过子域名来区分不同的系统。
  • CORS配置:配置跨域资源共享(CORS),允许不同域名之间的请求。
  • JSONP:使用JSONP技术绕过同源策略,但这种方法只支持GET请求。

问题2:会话同步问题

原因:不同服务器之间的会话信息无法同步。

解决方法

  • 集中式会话存储:使用Redis或Memcached等集中式存储来保存会话信息。
  • 无状态会话:通过JWT(JSON Web Token)实现无状态会话管理。

问题3:安全性问题

原因:跨域认证可能带来安全风险,如CSRF攻击。

解决方法

  • 使用HTTPS:确保所有通信都通过HTTPS加密。
  • CSRF Token:在每个请求中包含一个CSRF Token,防止跨站请求伪造攻击。

示例代码

以下是一个基于JWT的单点登录示例:

后端(Node.js)

代码语言:txt
复制
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');
});

前端(JavaScript)

代码语言:txt
复制
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);
}

参考链接

通过以上方法,可以实现不同域名之间的单点登录,并解决常见的跨域和安全问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

领券