Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Authlib 单点登录库初体验及踩坑

Authlib 单点登录库初体验及踩坑

作者头像
Ewdager
发布于 2020-07-14 06:52:12
发布于 2020-07-14 06:52:12
1.8K01
代码可运行
举报
文章被收录于专栏:Gvoidy备份小站Gvoidy备份小站
运行总次数:1
代码可运行

起因

项目突然要接入TX云,理所应当的要使用tx的单点登录了。于是乎,经过各方推荐,使用了大名鼎鼎的Authlib库。

初体验

经过各方文档,整理了一下,在Flask中使用Authlib相当简单。如果是接入有名的OAuth2站点如GithubGoogle这种,直接使用官方已经封装好的类即可快速实现,但此处使用的是TX方为工业互联网平台新搭建的OAuth2服务,理所应当不能直接使用。但仍可以使用较为便捷的封装进Flask中的认证方法,具体步骤如下:

新建存储Token的表

根据存储的access_token校验后续接口用户登录情况。 其中refresh_tokenaccess_token过期后,下次去OAuth2服务器请求新的Token的字段。如果在注册Authlib对象时写了update方法,即可自动更新token。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from app.models.base import db, Base


class OAuth2Token(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(40))
    token_type = db.Column(db.String(40))
    access_token = db.Column(db.String(200))
    refresh_token = db.Column(db.String(200))
    expires_in = db.Column(db.Integer())
    user_id = db.Column(db.Integer(), db.ForeignKey("user.id"))
    user = db.relationship("User", backref=db.backref("auth_token", lazy="dynamic"))

    def to_token(self):
        return dict(
            access_token=self.access_token,
            token_type=self.token_type,
            refresh_token=self.refresh_token,
            expires_in=self.expires_in,
        )

    @staticmethod
    def save_token(response):
        with db.auto_commit():
            oauth = OAuth2Token()
            oauth.name = 'tencent'
            oauth.access_token = response['access_token']
            oauth.token_type = response['token_type']
            oauth.expires_in = response['expires_in'] if 'expires_in' in response else None
            oauth.refresh_token = response['refresh_token'] if 'refresh_token' in response else None
            oauth.user_id = response['user_id'] if 'user_id' in response else None
            db.session.add(oauth)

创建oauth对象

authlib会自动从flask的全局configapp/config/setting.py中读取你设置的{YOUR_NAME}_CLIENT_ID{YOUR_NAME}__CLIENT_SECRET

authorize_url中填写第一步跳转到单点登录接口的url,access_token_url填写从单点登录服务器拿到code和state后,换取token的地址。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from authlib.integrations.flask_client import OAuth
from app.models.oauth import OAuth2Token
from flask import g
from app.models.base import db

from app.config.setting import TENCENT_CLIENT_ID, TENCENT_CLIENT_SECRET


def fetch_token(name):
    token = OAuth2Token.query.filter_by(name=name, user_id=g.user.uid).first()
    return token.to_token()


def update_token(name, token, refresh_token=None, access_token=None):
    if refresh_token:
        item = OAuth2Token.filter_by(name=name, refresh_token=refresh_token).first()
    elif access_token:
        item = OAuth2Token.filter_by(name=name, access_token=access_token).first()
    else:
        return
    if not item:
        return
    # update old token
    item.access_token = token['access_token']
    item.refresh_token = token.get('refresh_token')
    item.expires_in = token['expires_in']
    db.session.commit()


oauth = OAuth(fetch_token=fetch_token, update_token=update_token)

tencent = oauth.register(
    name='tencent',
    access_token_url=f'{CloudIndustryHost_internet}',
    access_token_params={
        'method': "GET",
        'grant_type': 'authorization_code'
    },
    authorize_url=f'{CloudIndustryHost_internet}',
    authorize_params=None,
    api_base_url=f'{CloudIndustryHost_internet}',
    client_kwargs={'scope': 'all'}
)

视图函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from flask import url_for, redirect, make_response

from app.models.oauth import OAuth2Token
from app.libs.oauthlib import tencent
from . import oauth as api
from .utils import *


@api.route('/login', methods=['GET', 'POST'])
def login():
    redirect_uri = url_for("v1.oauth+auth", _external=True)
    return tencent.authorize_redirect(redirect_uri)


@api.route('/redirect', methods=['GET', 'POST'])
def auth():
    token_info = tencent.authorize_access_token()

    OAuth2Token.save_token(token_info)
    response = make_response(redirect('/'))
    response.set_cookies('session_id', token_info['access_token'])

将oauth对象注册进flask app

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from app.libs.oauthlib import oauth


app = create_app()

oauth.init_app(app)

以上基本就能正常愉快的完成单点登录的全过程啦~

踩坑

好吧,实际上并不是这么一帆风顺的,在取得返回的code的视图函数中authorize_access_token()这一步一直碰到一个JSONDecodeError: Extra data: line 1 column 5 - line 1 column 19 (char 4 - 18)json无法序列化的bug。

经过进入Authlib的源码中深入调查,发现在fetch_token()这一步中,用OAuth服务器返回的code、states等参数向获取token的接口发请求时直接报404了。

反复查看文档发现地址并没有填错,最后发现,TX云那边使用的是GET方法拿token,而OAuthlibfetch_token()方法默认使用的是POST方法!!!

而要额外设置fetch_token()的方法需要再编写oath对象时,在access_token_params中加入所需要的方法。

authorize_access_token()方法会默认将access_token_params作为**kwarg传入后续的内部函数中,即可设置fetch_token()的参数。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Flask 博客接入第三方登录
Flask不像Django一样有各种现成的组件可以选用,Flask的各种扩展也不那么「开箱即用」。在我的博客项目中,我选用的是Authlib,它是国内的一名Python资深开发者@lepture开发的一款全面完善的OAuth认证库。大家可能在别的教程里会看到用的是flask-oauthlib,它们的作者其实是同一人,而且在2019年的今天,我绝对会推荐你用Authlib而不是flask-oauthlib。
岂不美哉Frost
2019/12/02
2.1K0
Flask 博客接入第三方登录
如何基于Security实现OIDC单点登录?
本文主要是给大家介绍 OIDC 的核心概念以及如何通过对 Spring Security 的授权码模式进行扩展来实现 OIDC 的单点登录。
陶陶技术笔记
2021/10/08
1.5K0
唯品会:授权流程说明
您的应用和唯品会开放平台对接后,需要获取有关用户(包括供应商)受限访问的隐私数据(如:商品、订单等),为保证用户数据的安全性与隐私性,您的应用需要取得用户的授权。在这种情况下,您的应用需要引导用户完成“使用唯品会帐号登录并授权”的流程。 目前的授权过程采用OAuth2.0协议,如果想了解这个协议更多的技术细节请参见官方说明:http://oauth.net/2/。 如果您是ISV软件商需要引导用户到授权页面,并且这个用户拥有一个唯品会的账号和密码,同时完成此账号和供应商ID的绑定认证。步骤如下: 1,ISV软件商完成应用审核和沙箱联调 2,使用ISV软件的供应商到VOP站点完成 供应商身份的认证操作 (注:接入MarketPlace无需此步骤) 3,ISV软件引导供应商完成授权 4,供应商可以正常使用ISV软件
凯哥Java
2019/06/28
5.1K1
唯品会:授权流程说明
全面介绍SSO(单点登录)
SSO英文全称Single SignOn,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。它是目前比较流行的企业业务整合的解决方案之一。
蒋老湿
2019/12/12
5.1K0
从头搭建一个flask鉴权系统之登陆
“ 从今天开始,准备从头开始搭建一个基于flask的鉴权系统,一点一滴,积累于生活”
周萝卜
2019/07/17
2.2K0
从头搭建一个flask鉴权系统之登陆
JAVA接入京东授权API
如果您的应用已和京东JOS对接,需要获取一些与用户紧密相关的信息(如订单、商品、促销等),为保证数据的安全性和隐私性,需要取得用户的同意,引导用户授权。JOS采用国际通用的OAuth2.0标准协议,支持网站、桌面客户端、ERP系统。如果要了解更多关于OAuth2.0的技术说明,请参考官方网站  http://oauth.net/2/  。目前,JOS的OAuth2.0支持以下方式获取Access Token。
凯哥Java
2019/06/28
3.2K0
Spring Cloud OAuth2 实现用户认证及单点登录
OAuth 2 有四种授权模式,分别是授权码模式(authorization code)、简化模式(implicit)、密码模式(resource owner password credentials)、客户端模式(client credentials),具体 OAuth2 是什么,可以参考这篇文章。(http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html)
古时的风筝
2019/10/24
2.1K0
Spring Cloud OAuth2 实现用户认证及单点登录
部署 Casdoor 身份认证管理系统并实现透过 OAuth2.0 登录到 WordPress
由于考虑到 XCTRA 未来可能会有非常多的子服务,如果全部采用单一认证可能会非常复杂,于是这几天一直在研究 IAM(Identity and Access Management)系统,在尝试了 Apache keycloak,JustAuthPlus 等开源项目后,最终选择了 Casdoor。
HikariLan贺兰星辰
2023/03/06
4.1K3
部署 Casdoor 身份认证管理系统并实现透过 OAuth2.0 登录到 WordPress
oauth2.0的学习与使用
栗子一: 小新现在想要使用一个“在线打印服务”来打印一些照片,同时小新的照片都存储在了“云网盘”上,按照传统的方式小新要怎么做呢?
向着百万年薪努力的小赵
2022/12/02
9570
OAuth2.0授权协议
通过用户授权,第三方服务访问用户存在其他服务上的资源,而不需用户将用户名密码直接传递的资源服务器的安全控制协议。
sucl
2019/09/05
7490
OAuth2.0授权协议
Apriso 通过飞书OAuth2.0实现单点二维码扫描登录
OAuth2.0介绍 OAuth(Open Authorization)是一个关于授权的开放网络标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容。OAuth在全世界得到广泛应用,目前的版本是2.0版。在Apriso MOM项目实施过程中也经常会碰到要求Apriso支持OAth2.0单点登录的需求。
李英杰同学
2023/09/02
2.6K1
Apriso 通过飞书OAuth2.0实现单点二维码扫描登录
JAVA接入淘宝授权API
如果您的应用和淘宝开放平台对接后,需要获取用户隐私信息(如:商品、订单、收藏夹等),为保证用户数据的安全性与隐私性,您的应用需要取得用户的授权。在这种情况下,您的应用需要引导用户完成“使用淘宝帐号登录并授权”的流程。
凯哥Java
2019/06/28
3.8K0
Spring官宣新家族成员:Spring Authorization Server!
8月17日,Spring官方宣布 Spring Authorization Server 已正式脱离实验状态,并进入Spring-Project家族! 背景 Spring Authorization Server (以下简称 SAS)是 Spring 团队最新开发适配 OAuth 协议的授权服务器项目,旨在替代原有的 Spring Security OAuth Server。 经过半年的开发和孵化,目前已经发布了 0.2.0 版本,已支持授权码、客户端、刷新、注销等 OAuth 协议。 目前 SAS 项
macrozheng
2021/09/22
1.6K0
Spring官宣新家族成员:Spring Authorization Server!
OAuth的改变
去年我写过一篇《OAuth那些事儿》,对OAuth做了一些简单扼要的介绍,今天我打算写一些细节,以阐明OAuth如何从1.0改变成1.0a,继而改变成2.0的。
LA0WAN9
2021/12/14
8190
认证授权的设计与实现
每个网站,小到一个H5页面,必有一个登录认证授权模块,常见的认证授权方式有哪些呢?又该如何实现呢?下面我们将来讲解SSO、OAuth等相关知识,并在实践中的应用姿势。
ruochen
2021/11/25
1.4K0
【实践】如何用GO实现OAuth2授权功能
本文讲解了用GO实现OAuth2授权功能的调试方法,具体代码请参考工程文件,原理请参考另外2篇文章《OAuth 2.0 的四种方式》, 《OAuth2介绍与使用》。
辉哥
2019/05/19
4.3K0
Spring Boot Security 整合 OAuth2 设计安全API接口服务
OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。本文重点讲解Spring Boot项目对OAuth2进行的实现,如果你对OAuth2不是很了解,你可以先理解 OAuth 2.0 - 阮一峰,这是一篇对于oauth2很好的科普文章。
程序员果果
2019/05/16
1.9K0
Spring SAS 0.2.0 上手教程正式上市 || SAS 0.2.0 上手教程
SAS 是 OAuth 2.1 协议的实现,不支持密码模式。 那么怎么扩展实现呢 ?下一篇文章我会分享扩展实现密码模式,欢迎关注。
冷冷
2021/08/24
1.2K0
spring security oauth2之refresh token
本文就来讲一讲spring security oauth2的refresh token方式
code4it
2018/09/17
3.9K0
【OIDC】基本概念
注意:不是 OAuth2.0 无法完成认证,而是 OAuth2.0 本身的认证过程缺乏统一的标准。
tonglei0429
2022/10/04
1.7K0
相关推荐
Flask 博客接入第三方登录
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验