网站首页 > 技术文章 正文
1.什么是单点登录
所谓单点登录,你可以简单的理解为有两个网站,这个两个网站的域名是不相同,但是它们同属于一家公司。当你在某一个网站登录输入完密码之后,你再去访问第二个网站时,就不需要再次输入密码了,可以直接显示登录状态。例如你在百度文库登录之后,再去百度知道,你发现也同样处于登录状态。
2.单点登录原理
单点登录最重要的是认证中心,假设有a网站和b网站,当你登录其中任何一个时,都会跳转到认证中心,实际的用户名和密码的验证是在这里完成的。
2.1认证中心如何区分子系统
登录时,都跳转到认证中心,那么认证中心怎么区分这次请求是从哪个网站来的呢?方法很简单,你登录a网站时,a网站的后台跳转到认证中心时,会将自己网站的网址作为参数(referer),这样,认证中心就知道是哪个子系统网站在登录了。
2.2认证中心登录后做什么
你在认证中心填写好用户名和密码登录后,认证中心会再次跳转到a网站,而且要带上一个ticket,这个很关键,同时设置session
2.3 a网站怎么办
对于a网站,请求里带有ticket,那么就对这个ticket进行验证,看他是不是认证中心颁发的(我的程序没有做这个验证),如果是呢,则登录成功
2.4 b网站如何登录
a网站登录后,你又想去b网站逛逛,和a网站一样,也要跳转到认证中心,可是不同于第一次跳转,在2.2中,已经设置了session,就说明已经在认证中心认证过了,所以认证中心这次会直接跳转到b网站,也带着ticket,b网站看到ticket,也去验证是否是认证中心颁发的,最后b网站成功登录。
3 代码构建
项目结构如下所示,项目使用的框架是python flask。
3.1 login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SSO</title>
<meta name="author" content="" />
<meta http-equiv="X-UA-Compatible" content="IE=7" />
<meta name="keywords" content="SSO" />
<meta name="description" content="SSO" />
</head>
<body>
<form method="POST" action="dologin?referer={{ referer }}">
account: <input type="username" name="username"><br>
password: <input type="password" name="password"><br>
<input type="submit" value="logon">
</body>
</html>
3.2 sso.py
#coding: utf8
import os
from datetime import timedelta
from flask import Flask, session, render_template, request, redirect
import urllib
app = Flask(__name__)
app.secret_key = '123456'
app.permanent_session_lifetime = timedelta(seconds=30 * 24 * 60 * 60)
@app.route('/login')
def login():
session.permanent = True
referer = request.args.get('referer', None)
if referer is not None:
referer = referer.strip()
if 'name' in session:
if referer is not None:
return redirect(referer + '?ticket=' + _makeTicket())
return render_template('login.html', **dict(referer=referer))
@app.route('/dologin',methods=['POST'])
def doLogin():
'''
这里没有真正的去进行验证,直接写session了,然后redirect了
'''
session.permanent = True
print request.args
print request.form
referer = request.args.get('referer', None)
if(request.form.get('username')== 'zhangsan') and (request.form.get('password')=='111111'):
print "username and password is right"
else:
return "username and passwprd is not right"
if referer is not None:
referer = urllib.unquote(referer.strip())
#不实现登录功能,直接设置登录态
_setLoginState()
if referer:
return redirect(referer + '?ticket=' + _makeTicket())
else:
return 'error'
def _setLoginState():
session['name'] = 'zhangsan'
def _makeTicket():
'''生成ticket,这里只是简单返回用户名,真实场景中可以使用des之类的加密算法'''
return 'zhangsan'
if __name__ == '__main__':
app.run(
host="0.0.0.0",
port=int("5200"),
debug=True
)
3.3 a.py
#coding: utf8
import os
from datetime import timedelta
from flask import Flask, session, redirect, url_for, request
import urllib
app = Flask(__name__)
app.secret_key = 'b123456'
app.permanent_session_lifetime = timedelta(seconds=24 * 60 * 60)
@app.route('/')
def index():
#表示存活期为浏览器进程的存活期
session.permanent = False
ticket = request.args.get('ticket', None)
#此处应该验证ticket是认证中心发布的
if ticket is not None:
session['name'] = ticket.strip()
#检测登录态
if 'name' in session:
return 'a登录成功'
else:
referer = urllib.quote('http://www.a.com:5201/')
return redirect('http://www.sso.com:5200/login?referer=' + referer)
if __name__ == '__main__':
app.run(
host="0.0.0.0",
port=int("5201"),
debug=True
)
3.4 b.py
#coding: utf8
import os
from datetime import timedelta
from flask import Flask, session, redirect, url_for, request
import urllib
app = Flask(__name__)
app.secret_key = 'a123456'
app.permanent_session_lifetime = timedelta(seconds=24 * 60 * 60)
@app.route('/')
def index():
#表示存活期为浏览器进程的存活期
session.permanent = False
ticket = request.args.get('ticket', None)
print session
if ticket is not None:
session['name'] = ticket.strip()
#检测登录态
if 'name' in session:
print session['name']
return 'b登录成功'
else:
referer = urllib.quote('http://www.b.com:5202/')
return redirect('http://www.sso.com:5200/login?referer=' + referer)
if __name__ == '__main__':
app.run(
host="0.0.0.0",
port=5202,
debug=True
)
注意:代码构建完成之后需要在window的hosts文件或者服务器的hosts文件中添加域名和ip的映射。
4.结果演示
首先在浏览器中输入http://www.a.com:5201,可以看到自动跳转到了http://www.sso.com:5200,并且调用了login接口
这个时候输入账号密码zhangsan/111111,会发现调用了dologin接口,并且带上了a网站的域名作为参数,验证通过后重新跳转到了www.a.com网站,并带上了ticket参数,并且显示了a网站登录成功的结果。
这个时候再去登录www.b.com,会发现,会先去www.sso.com认证一下,发现session已经存在之后,就会跳回www.b.com,并且设置session。所以在没有输入密码的情况下,b网站也成功登录。
猜你喜欢
- 2025-05-25 Python从放弃到入门:公众号历史文章爬取为例谈快速学习技能
- 2025-05-25 你要偷偷的学Python,然后惊呆所有人(第十一天)
- 2025-05-25 玛森:Python爬虫书籍推荐
- 2025-05-25 Python-web开发必备的9个知识点
- 2025-05-25 通过https协议发送skype信息给朋友python
- 2025-05-25 python使用技巧之环境搭建(办公自动化方向)
- 2025-05-25 接口测试实战:Jmeter与Python结合测试异步接口场景
- 2025-05-25 阿六带你用python appium搭建app自动化测试环境
- 2025-05-25 Python应该怎么学?
- 2025-05-25 揭秘Instagram登录逆向,以及完整的python代码实现
- 05-25Python 3.14 t-string 要来了,它与 f-string 有何不同?
- 05-25Python基础元素语法总结
- 05-25Python中的变量是什么东西?
- 05-25新手常见的python报错及解决方案
- 05-2511-Python变量
- 05-2510个每个人都是需要知道Python问题
- 05-25Python编程:轻松掌握函数定义、类型及其参数传递方式
- 05-25Python基础语法
- 257℃Python短文,Python中的嵌套条件语句(六)
- 257℃python笔记:for循环嵌套。end=""的作用,图形打印
- 256℃PythonNet:实现Python与.Net代码相互调用!
- 251℃Python操作Sqlserver数据库(多库同时异步执行:增删改查)
- 251℃Python实现字符串小写转大写并写入文件
- 106℃原来2025是完美的平方年,一起探索六种平方的算吧
- 90℃Python 和 JavaScript 终于联姻了!PythonMonkey 要火?
- 81℃Ollama v0.4.5-v0.4.7 更新集合:Ollama Python 库改进、新模型支持
- 最近发表
- 标签列表
-
- python中类 (31)
- python 迭代 (34)
- python 小写 (35)
- python怎么输出 (33)
- python 日志 (35)
- python语音 (31)
- python 工程师 (34)
- python3 安装 (31)
- python音乐 (31)
- 安卓 python (32)
- python 小游戏 (32)
- python 安卓 (31)
- python聚类 (34)
- python向量 (31)
- python大全 (31)
- python次方 (33)
- python桌面 (32)
- python总结 (34)
- python浏览器 (32)
- python 请求 (32)
- python 前端 (32)
- python验证码 (33)
- python 题目 (32)
- python 文件写 (33)
- python中的用法 (32)