作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
应用程序通常需要登录功能,以便用户可以保存数据, 创建自己的个人资料, 或者只是为了限制对敏感资源的访问. 在现代应用程序中, 用户希望有标准的登录相关功能,如电子邮件验证, 密码重置, 或者多因素身份验证. 这些功能虽然是必要的,但并不容易实现,通常也不是应用程序的主要业务.
在用户方面, 他们可能不想经历冗长的注册过程,因为他们需要创建和记住另一个电子邮件和密码对. 没有合适的密码管理器, 用户倾向于重复使用相同的密码,这在安全性方面是可怕的.
单点登录(SSO),通常被用户称为 登录社交媒体 按钮的发明就是为了解决这个问题. 对于用户来说,不用再经历另一个痛苦的注册过程是很容易的. 对于企业来说,消除用户的摩擦总是一个巨大的胜利 开发人员,所有与登录相关的功能现在都已安装 委托 给身份提供者(Facebook, 谷歌, Twitter等).),这意味着更少的代码! 你的应用很简单 信托基金 身份提供者执行其验证用户身份的工作.
SSO通常由 OpenId 连接(OIDC)或SAML协议. SAML主要用于企业应用程序. OIDC建立在OAuth2之上,被Facebook、谷歌等社交身份提供商使用. 在这篇文章中,我们将关注OIDC/OAuth2协议.
在这个瓶登录教程中, 我们将编写一个循序渐进的指南,将SSO登录按钮添加到瓶应用程序中,使用SimpleLogin和Facebook作为身份提供者. 这可以在不使用任何外部库的情况下完成,但这是为了简化OAuth的复杂性, 我们将使用 Requests-OAuthlib,一个集成OAuth提供程序的库. 如果您对从头开始实现SSO感兴趣,请查看 实现SSO登录-原始方式.
在本文结束时,你应该有一个瓶应用程序,具有以下页面:
本教程的所有代码都可以在 瓶-social-登录-example库.
安装 瓶
和 Requests-OAuthlib
. 你也可以用 virtualenv
or pipenv
隔离环境.
PIP安装瓶 requests_oauthlib
创建 应用程序.py
在主页上显示登录按钮的路由:
import 瓶
应用程序 = 瓶.瓶(__name__)
@应用程序.route("/")
def index():
return """
Login
"""
if __name__ == '__main__':
应用程序.run(debug=True)
让我们运行这个应用程序并验证一切正常:
python应用程序.py
当您打开http://localhost:5000时,应该会看到这个页面. 完整的代码是在 step1.py.
目前有数百家(如果不是数千家的话)身份提供商,其中最受欢迎的是Facebook, 谷歌, GitHub, 和Instagram. 对于这篇文章, SimpleLogin 是因为它对开发人员友好而选择的. 但是,相同的代码将适用于任何OAuth2身份提供程序. (免责声明:我恰好是SimpleLogin的联合创始人, 这可能是我决定使用它的一个因素.)
请前往 SimpleLogin 并创建一个帐户,如果你还没有一个,然后在开发者选项卡创建一个新的应用程序.
在应用程序详细页面, 请复制您的AppID和AppSecret并将它们保存到变量环境中. 在OAuth术语中,客户端实际上是指第三方应用程序.e.,你的应用程序. 我们可以将这些值直接放入代码中,但最好将凭据保存到环境变量中. 这也是第三个因素 十二要素.
导出CLIENT_ID={您的AppID}
export CLIENT_SECRET={你的AppSecret}
In 应用程序.py
请将这些行添加到文件的顶部以获得 客户机id
和 客户的秘密
.
进口操作系统
CLIENT_ID = os.环境.get (" CLIENT_ID”)
CLIENT_SECRET = os.环境.get(“CLIENT_SECRET”)
请在顶部添加这些OAuth url 应用程序.py
这将在下一步中用到. 它们也可以在OAuth端点页面上复制.
AUTHORIZATION_BASE_URL = "http://应用程序 . url ".simple登录.io / oauth2 /授权”
TOKEN_URL = "http://应用程序 . url ".simple登录.io / oauth2 /令牌”
USERINFO_URL = "http://应用程序 . url ".simple登录.io / oauth2 /用户信息”
由于我们现在不想担心设置SSL,让我们告诉 Requests-OAuthlib
使用纯HTTP是可以的:
这允许我们使用普通的HTTP回调
os.环境["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
与往常一样,这一步的代码是打开的 步骤2.py.
当用户点击登录按钮时:
code
在URL中,你的应用将使用这个URL来交换一个 访问令牌
这允许您稍后从服务提供者获取用户信息.因此我们需要两条路线:a 登录
路由,将用户重定向到标识提供者和 回调
路由接收 code
用它来交换 访问令牌
. 回调路由还负责显示用户信息.
@应用程序.route("/登录")
def登录():
simple登录 = requests_oauthlib.OAuth2Session (
CLIENT_ID, redirect_uri="http://localhost:5000/回调"
)
authorization_url, _ = simple登录.authorization_url(AUTHORIZATION_BASE_URL)
返回瓶.重定向(authorization_url)
@应用程序.route("/回调")
def 回调():
simple登录 = requests_oauthlib.OAuth2Session (CLIENT_ID)
simple登录.fetch_token(
TOKEN_URL, client_secret=CLIENT_SECRET, authorization_response=瓶.request.url
)
user_info = simple登录.get(USERINFO_URL).json()
return f"""
User information:
Name: {user_info["name"]}
Email: {user_info["电子邮件"]}
Avatar
Home
"""
单击登录按钮将使您完成以下流程. 完整的代码可以在 GitHub在步骤3.py.
Facebook的建立, 谷歌, 和Twitter的登录有点复杂,需要额外的步骤,如设置SSL或选择正确的范围. 这些都超出了本文的讨论范围.
除了复杂的UI, 整合Facebook最困难的部分可能是找到一种方法在本地HTTPS上提供你的web应用,因为新版本的Facebook SDK不允许本地纯HTTP. 我建议使用 Ngrok,一个免费的工具,有一个快速的HTTPS URL.
请前往 http://Developers.facebook.com
然后创建一个新的应用程序:
然后在下一个界面中选择“整合Facebook登录”:
点击左侧的“设置/基本”,复制 应用程序ID 和 应用程序的秘密. 它们实际上是OAuth 客户机id
和 端秘密
.
更新 客户机id
和 端秘密
.
export FB_CLIENT_ID={您的脸谱网 AppId}
export FB_CLIENT_SECRET={你的脸谱网 AppSecret}
更新AUTHORIZATION_BASE_URL和TOKEN_URL:
FB_AUTHORIZATION_BASE_URL = "http://www . net ".脸谱网.com/dialog/oauth”
FB_TOKEN_URL = "http://graph.脸谱网.com/oauth/access_token”
主页:
@应用程序.route("/")
def index():
return """
登录Facebook
"""
如果应用程序在后面服务 ngrok
使用 Ngrok HTTP 5000
命令,我们需要将当前URL设置为ngrok URL.
运行“Ngrok HTTP 5000”后获得的ngrok url
URL = "http://abcdefgh ".ngrok.io"
请确保将url添加到您的Facebook登录/设置,有效OAuth重定向uri设置:
为了访问用户的电子邮件,您需要添加 电子邮件
成 范围
:
FB_SCOPE = ["电子邮件"]
@应用程序.路线(“/ fb-登录”)
def登录():
Facebook = requests_oauthlib.OAuth2Session (
FB_CLIENT_ID, redirect_uri=URL + "/fb-回调", 范围=FB_SCOPE
)
Authorization_url, _ = 脸谱网.authorization_url (FB_AUTHORIZATION_BASE_URL)
返回瓶.重定向(authorization_url)
的 回调
route的情况要复杂一些,因为Facebook需要进行合规修复:
from requests_oauthlib.compliance_fixes import 脸谱网_compliance_fix
@应用程序.route("/fb-回调")
def 回调():
Facebook = requests_oauthlib.OAuth2Session (
FB_CLIENT_ID, 范围=FB_SCOPE, redirect_uri=URL + "/fb-回调"
)
# we need to 应用程序ly a fix for Facebook 在这里
脸谱网 = 脸谱网_compliance_fix(脸谱网)
脸谱网.fetch_token(
FB_TOKEN_URL,
client_secret=FB_CLIENT_SECRET,
authorization_response=瓶.request.url,
)
# Fetch a protected resource, i.e. user profile, via Graph API
脸谱网_user_data = 脸谱网.get(
"http://graph.脸谱网.com/me?fields=id,name,电子邮件,picture{url}"
).json()
电子邮件 = 脸谱网_user_data["电子邮件"]
name = 脸谱网_user_data["name"]
picture_url = 脸谱网_user_data.get("picture", {}).get("data", {}).get("url")
return f"""
User information:
Name: {name}
Email: {电子邮件}
Avatar
Home
"""
现在,当点击登录Facebook,你应该能够通过整个流程.
完整的代码是在 脸谱网.py.
祝贺您——您已经成功地将SSO登录集成到瓶应用程序中!
为简单起见,本教程没有提到其他OAuth概念,例如 范围 和 状态,这对于防御跨站点请求伪造攻击非常重要. 您可能还需要将用户信息存储在数据库中,这在本文中没有涉及.
该应用还需要在生产环境中用http提供服务,这在今天很容易做到 让我们加密.
oauth快乐!
瓶中的登录页面基本上是一个HTML页面. 在瓶中处理登录的棘手部分可能是在会话中存储用户登录状态, 这通常是由烧瓶登录扩展处理. 这个扩展还附带了方便的登录_required装饰器,限制对经过身份验证的用户的访问.
单点登录使用户只需登录一次,就可以访问多个应用程序. 对于企业用户,这通常以应用程序门户的形式出现. 对于私人用户来说,最流行的单点登录形式可能是“登录Facebook”按钮.
单点登录是一种将身份验证“委托”给称为“身份提供者”的另一方的系统.应用程序和身份提供者之间的通信通常由SAML协议(主要用于企业环境)或OIDC/OAuth2(主要用于消费者环境)处理。.
单点登录为用户和应用程序开发人员提供了双重优势. 用户不需要记住另一个密码,登录速度也很快. 为开发人员, 他们不必实现与身份验证相关的功能,也不必担心存储用户电子邮件/密码的安全隐患.
OAuth是一种授权协议,它规定了应用程序如何访问用户资源. OIDC (OpenID Connect)是一种“身份验证”协议,是在OAuth之上创建的一层. OIDC和SAML通常是支持单点登录的协议.
您需要一个身份提供程序来测试SSO. 有成千上万的身份提供者,其中大多数都遵循OIDC. 对于不需要特定社交数据(Facebook feed)的应用程序, 推特, 等), 使用SimpleLogin作为身份提供者可能是一个快速的解决方案,因为它“对开发人员友好”.”
瓶是Python中流行的web框架. 用它的表现力, 通常用瓶编写的代码可以很容易地翻译成其他语言和框架.
微框架中的“微”意味着瓶只关注web,不包括数据库ORM之类的东西, 缓存管理, 或身份验证. 这些特性作为扩展提供,可以根据您的需要启用.
世界级的文章,每周发一次.
世界级的文章,每周发一次.