用 Flask 来写个轻博客 (23) — 应用 OAuth 来实现 Facebook 第三方登录

简介: 目录目录前文列表扩展阅读第三方登录流程OAuth应用 OAuth 实现 Facebook 第三方登录实现效果前文列表用 Flask 来写个轻博客 (1) — 创建项目 用 Flask 来写个轻博客 (2) — Hello World!...

目录

前文列表

用 Flask 来写个轻博客 (1) — 创建项目
用 Flask 来写个轻博客 (2) — Hello World!
用 Flask 来写个轻博客 (3) — (M)VC_连接 MySQL 和 SQLAlchemy
用 Flask 来写个轻博客 (4) — (M)VC_创建数据模型和表
用 Flask 来写个轻博客 (5) — (M)VC_SQLAlchemy 的 CRUD 详解
用 Flask 来写个轻博客 (6) — (M)VC_models 的关系(one to many)
用 Flask 来写个轻博客 (7) — (M)VC_models 的关系(many to many)
用 Flask 来写个轻博客 (8) — (M)VC_Alembic 管理数据库结构的升级和降级
用 Flask 来写个轻博客 (9) — M(V)C_Jinja 语法基础快速概览
用 Flask 来写个轻博客 (10) — M(V)C_Jinja 常用过滤器与 Flask 特殊变量及方法
用 Flask 来写个轻博客 (11) — M(V)C_创建视图函数
用 Flask 来写个轻博客 (12) — M(V)C_编写和继承 Jinja 模板
用 Flask 来写个轻博客 (13) — M(V)C_WTForms 服务端表单检验
用 Flask 来写个轻博客 (14) — M(V)C_实现项目首页的模板
用 Flask 来写个轻博客 (15) — M(V)C_实现博文页面评论表单
用 Flask 来写个轻博客 (16) — MV(C)_Flask Blueprint 蓝图
用 Flask 来写个轻博客 (17) — MV(C)_应用蓝图来重构项目
用 Flask 来写个轻博客 (18) — 使用工厂模式来生成应用对象
用 Flask 来写个轻博客 (19) — 以 Bcrypt 密文存储账户信息与实现用户登陆表单
用 Flask 来写个轻博客 (20) — 实现注册表单与应用 reCAPTCHA 来实现验证码
用 Flask 来写个轻博客 (21) — 结合 reCAPTCHA 验证码实现用户注册与登录
用 Flask 来写个轻博客 (22) — 实现博客文章的添加和编辑页面

扩展阅读

理解OAuth 2.0

第三方登录流程

这里写图片描述

Resource Owner:资源所有者,本文中又称”用户”(user)。
Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。
Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。

(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。

不难看出来,上面六个步骤之中,(B) 是整个流程的关键,有了这个授权以后,客户端就可以获取令牌,进而凭令牌获取资源。 那用户怎样才能给于客户端授权? 我们可以使用 OAuth 来实现.

OAuth

OAuth 的作用就是让”客户端(blog application)”安全可控地获取”服务商用户(Facebook User)”帐号的授权,与”服务商提供商(Facebook)”进行互动。

OAuth在”客户端”与”服务提供商”之间,设置了一个授权层(authorization layer)。”客户端”不能直接登录”服务提供商”,只能登录授权层,以此将用户与客户端分离。”客户端”登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。

“客户端”登录授权层以后,”服务提供商”根据令牌的权限范围和有效期,向”客户端”开放用户储存的资料。由此可见, 用户账户的安全性就交由这些知名的可靠的”服务提供商”来处理了, 可以更好的降低用户登录 blog 的信任成本.

应用 OAuth 实现 Facebook 第三方登录

  • 安装
pip install Flask-OAuth
pip freeze > requirements.txt
  • facebook developer 上创建 facebook 并获取 app_id 和 app_Secret, 并注册授权站点, 这里我们使用 http://localhost:5000/
    这里写图片描述

  • 初始化 OAuth 对象, 并使用该对象来获取 facebook 对象
    vim extensions.py

from flask_oauth import OAuth

# Create the Flask-OAuth's instance
oauth = OAuth()

# facebook 第三方登录接口
# Create the auth object for facebook.
facebook = oauth.remote_app(
    'facebook',
    base_url='https://graph.facebook.com/',
    request_token_url=None,
    access_token_url='/oauth/access_token',
    authorize_url='https://www.facebook.com/dialog/oauth',
    consumer_key='<Your_app_number>',
    consumer_secret='<Your_app_secret>',
    request_token_params={'scope': 'email'})

@facebook.tokengetter
def get_facebook_token():
    return session.get('facebook_oauth_token')

NOTE 1: facebook 对象是上述步骤中创建的 facebook 应用对象, 其包含了认证的结果信息和请求授权的 facebook user 信息. facebook 是完成第三方登录流程的接口对象.

NOTE 2: 方法 get_facebook_oauth_token() 获取 facebook 发放的 token. 当成功创建 facebook 对象并完成授权时, 表示 client(blog) 成功的向 Authorization server 完成认证并接受到服务端的 token, 并保存在 session 中. 然后 Client 就可以使用这个 token 去访问 facebook 的资源(账户权限资源)了.

  • 实现在 client 触发用户授权的逻辑
    vim jmilkfansblog/controllers/main.py
from jmilkfansblog.extensions import openid, facebook


# 当访问 /facebook 时, 触发授权流程
main_blueprint.route('/facebook')
def facebook_login():
    return facebook.authorize(
        callback=url_for('main.facebook_authorized',
                         next=request.referrer or None,
                         _external=True))


# 该视图会接受从 facebook 认证服务器返回的 resp 对象, 可以通过 resp 对象来判断 Client 在 Server 上的认证结果.
@main_blueprint.route('/facebook/authorized')
@facebook.authorized_handler
def facebook_authorized(resp):
    if resp is None:
        return 'Access denied: reason=%s error=%s' % (
            request.args['error_reason'],
            request.args['error_description'])

    session['facebook_oauth_token'] = (resp['access_token'], '')

    me = facebook.get('/me')

    if me.data.get('first_name', False):
        facebook_username = me.data['first_name'] + " " + me.data['last_name']
    else:
        facebook_username = me.data['name']

    user = User.query.filter_by(username=facebook_username).first()
    if user is None:
        user = User(id=str(uuid4()), username=facebook_username, password='jmilkfan')
        db.session.add(user)
        db.session.commit()

    flash('You have been logged in.', category='success')

    return redirect(url_for('blog.home'))
  • 实现登录链接
<div class="row">
  <div class="form-group">
    <a href="{{ url_for('main.facebook_login') }}">Login via Facebook</a>
  </div>
</div>

实现效果

访问 /faceboook/authorized 进入用户授权页面:
这里写图片描述
NOTE: 需要首先登录到 facebook 之后, 才能够进入授权的处理流程.

授权并登录成功:
这里写图片描述

相关文章
|
4月前
|
关系型数据库 数据库连接 数据库
Flask应用基础入门总结
Flask应用基础入门总结
43 0
|
3天前
|
API 数据库 数据安全/隐私保护
Flask框架在Python面试中的应用与实战
【4月更文挑战第18天】Django REST framework (DRF) 是用于构建Web API的强力工具,尤其适合Django应用。本文深入讨论DRF面试常见问题,包括视图、序列化、路由、权限控制、分页过滤排序及错误处理。同时,强调了易错点如序列化器验证、权限认证配置、API版本管理、性能优化和响应格式统一,并提供实战代码示例。了解这些知识点有助于在Python面试中展现优秀的Web服务开发能力。
20 1
|
3天前
|
SQL 中间件 API
Flask框架在Python面试中的应用与实战
【4月更文挑战第18天】**Flask是Python的轻量级Web框架,以其简洁API和强大扩展性受欢迎。本文深入探讨了面试中关于Flask的常见问题,包括路由、Jinja2模板、数据库操作、中间件和错误处理。同时,提到了易错点,如路由冲突、模板安全、SQL注入,以及请求上下文管理。通过实例代码展示了如何创建和管理数据库、使用表单以及处理请求。掌握这些知识将有助于在面试中展现Flask技能。**
12 1
Flask框架在Python面试中的应用与实战
|
8天前
|
缓存 监控 数据库
Flask性能优化:打造高性能Web应用
【4月更文挑战第16天】本文介绍了提升Flask应用性能的七大策略:优化代码逻辑,减少数据库查询,使用WSGI服务器(如Gunicorn、uWSGI),启用缓存(如Flask-Caching),优化数据库操作,采用异步处理与并发(如Celery、Sanic),以及持续监控与调优。通过这些手段,开发者能有效优化Flask应用,适应大型或高并发场景,打造高性能的Web服务。
|
8天前
|
监控 安全 数据库
Flask应用部署指南:从开发到生产环境
【4月更文挑战第16天】本文是Flask应用从开发到生产的部署指南,涵盖开发环境准备、应用开发、部署方案选择、生产环境配置、应用部署、监控与维护。确保安装Python、Flask及依赖库,使用文本编辑器或IDE编写代码,关注应用安全与性能。选择WSGI服务器、Docker或云服务平台部署,配置生产环境,确保安全性,然后部署应用并进行监控维护,定期更新修复问题,保证应用稳定运行。
|
8天前
|
JSON 安全 API
Flask-Login与Flask-RESTful:扩展你的应用功能
【4月更文挑战第16天】本文介绍了两个实用的Flask扩展——Flask-Login和Flask-RESTful。Flask-Login提供用户认证和会话管理,简化了登录、注销和保护路由的逻辑。而Flask-RESTful则助力构建RESTful API,支持多种HTTP方法和请求解析。通过这两个扩展,开发者能轻松增强Flask应用的功能性,实现安全的用户认证和高效的API交互。
|
9天前
|
数据库 开发者 Python
Python中使用Flask构建简单Web应用的例子
【4月更文挑战第15天】Flask是一个轻量级的Python Web框架,它允许开发者快速搭建Web应用,同时保持代码的简洁和清晰。下面,我们将通过一个简单的例子来展示如何在Python中使用Flask创建一个基本的Web应用。
|
1月前
|
存储 Java UED
如何在Flask应用中实现异步编程?
【2月更文挑战第27天】【2月更文挑战第96篇】如何在Flask应用中实现异步编程?
|
1月前
|
JSON API 数据格式
构建高效Python Web应用:Flask框架与RESTful API设计实践
【2月更文挑战第17天】在现代Web开发中,轻量级框架与RESTful API设计成为了提升应用性能和可维护性的关键。本文将深入探讨如何使用Python的Flask框架来构建高效的Web服务,并通过具体实例分析RESTful API的设计原则及其实现过程。我们将从基本的应用架构出发,逐步介绍如何利用Flask的灵活性进行模块化开发,并结合请求处理、数据验证以及安全性考虑,打造出一个既符合标准又易于扩展的Web应用。
646 4
|
2月前
|
数据库 开发者 Python
Python在Web开发中的应用:Flask与Django框架介绍与实践
Python在Web开发中的应用:Flask与Django框架介绍与实践