利用本地HTTPS模拟环境为FastAPI框架集成FaceBook社交三方登录
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_174
提起社交,就不得不说马克·扎克伯格(Mark Zuckerberg)一手创办的社交网络(FaceBook)。进入2020年,FaceBook的全球用户数已经突破了30亿,这是什么概念?全球人口大约70亿,除开中国14亿,还有56亿。国外市场是四倍于中国的潜在市场,扣除短期内有上网限制的人群,那也是两倍以上。站在全球视角看问题,说微信、支付宝偏安一隅,其实也并不为过。所以为你的平台集成全球最大用户基数的社交登录系统,显然可以为你带来更多的潜在用户,本次我们使用当红炸子鸡FastAPI框架来集成FaceBook的三方登录。
首先在https://developers.facebook.com/上面注册开发者账号,并且创建一个应用:
输入一个应用名称
创建成功之后,需要加应用id(appid)和应用秘钥记录下来,之后会用到:
这之后添加产品,选择FaceBook登录,并且进行设置,将回调网址配置好,这是登录成功后跳转回网址的地址:
这里需要注意的是,FaceBook官方对安全性要求很高,它要求三方的应用强制使用HTTPS协议,而一般情况下本地环境的解决方案就是使用自签证书,所以这里使用一种更加简单友好的方式生成本地https证书,并且信任自签CA的方案——mkcert。
mkcert是一个使用go语言编写的生成本地自签证书的小程序,具有跨平台,使用简单,支持多域名,自动信任CA等一系列方便的特性可供本地开发时快速创建https环境使用。
安装方式也非常简单,由于Go lang的静态编译和跨平台的特性,官方提供各平台预编译的版本,直接下载到本地,给可执行权限(Linux/Unix需要)就可以了。Github地址:https://github.com/FiloSottile/mkcert
如果是Win10平台,可以使用Chocolatey来安装:
choco install mkcert
Mac os平台则可以使用Homebrew,非常方便:
brew install mkcert
安装成功之后,运行命令将CA证书加入本地可信CA:
mkcert -install
在Win10的可信CA列表可以找到该证书:
同理在Mac OS的证书列表同样也可以找到:
接下来我们就可以生成自签证书了,比如本地通过localhost或者127.0.0.1来访问你的web应用:
mkcert localhost 127.0.0.1 ::1
会自动生成:
liuyue:blog liuyue$ mkcert localhost 127.0.0.1 ::1
Created a new local CA at "/Users/liuyue/Library/Application Support/mkcert" ????
Warning: the local CA is not installed in the system trust store! ️
Warning: the local CA is not installed in the Firefox trust store! ️
Warning: the local CA is not installed in the Java trust store! ️
Run "mkcert -install" to avoid verification errors ️
Created a new certificate valid for the following names ????
- "localhost"
- "127.0.0.1"
- "::1"
The certificate is at "./localhost+2.pem" and the key at "./localhost+2-key.pem"
可以看到成功生成了localhost+2.pem证书文件和localhost+2-key.pem私钥文件。
编写main.py用来运行FastAPI服务:
from user import router
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from model import database
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")
app.include_router(router)
@app.on_event("startup")
async def startup():
await database.connect()
@app.on_event("shutdown")
async def shutdown():
await database.disconnect()
@app.get("/")
def read_root():
return {"Hello": "World"}
现在将证书和私钥文件拷贝到你的FastAPI项目目录中,启动项目,这里启动时需要指定证书:
uvicorn main:app --ssl-keyfile localhost+2-key.pem --ssl-certfile localhost+2.pem
访问 https://localhost:8000/,注意这里的协议要写为https
可以看到chrome浏览器已经认为这个网络服务是安全的了。
由于我们现在已经安全部署了本地服务,就可以继续操作FaceBook了,编写login.html作为登录页面:
<html>
<head>
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/zh_CN/sdk.js#xfbml=1&version=v8.0&appId=337974204227205&autoLogAppEvents=1" nonce="BBgy4tba"></script>
<script>
function login() {
FB.login(function(response){
console.log(response);
});
}
</script>
</head>
<body>
<h1>Facebook社交登录</h1>
<div class="fb-login-button" data-size="large" data-button-type="continue_with" data-layout="default" data-auto-logout-link="false"
data-onlogin="login" data-use-continue-as="false" data-width=""></div>
</body>
</html>
登录页面中需要将代码里的appid改为你自己的自建应用的id。
将login.html放入到FastAPI项目的static目录,随后访问它:https://localhost:8000/static/login.html
注意这里访问页面也必须采用https协议,之后点击按钮,用你的FaceBook账号登录:
如果登录成功,FaceBook会将回调的用户id以及accesstoken返回给当前页面,前端只要进行获取就可以了:
一般情况下,前端获取到秘钥之后,后端需要对其进行验证,用来防止有人进行篡改或者使用其他应用的appid来进行请求。
这里我们编写一个后端的视图,用来验证用户token:
@router.get("/checklogin/")
async def check_login():
res = requests.get("https://graph.facebook.com/debug_token?access_token=337974204227205%7Cdc75d0a1fb30f2952db3a6a39e3f0ac0&input_token=EAAEzYsBi3oUBAHQQ9w7jSW95FcZBflMnib1cHUpf9eMBnuSvNcvvg31oKtIGoZA9kYtpq3OLMNSgY01ErgZA21PDRqdz7APrdZAXFJ9k43TnJXH8ZADb9Cjr2JEevZCdPpyTOpsZBvxE7RC63JjxZBr60iNQjWlfwwGBqdS2knhXBebpWGezrkg5WLRuBaUi3IdZBIBozQp1KMdDUmNWyR365")
res = json.loads(str(res.text))
return res
这里需要注意的是User-token为用户登录的token(就是上面用户登录返回的accessToken),App-token是由appId和appSecret拼接而成,格式为 {appId}%7C{appSecret},%7C就是|urlencode之后的编码。
访问FastAPI地址:https://localhost:8000/checklogin/
可以看到验证成功,我们可以将access_token存到后台即可,以后获取用户信息的时候就直接调用。
紧接着我们就编写接口用token来换取用户信息:
@router.get("/getinfo/")
async def userinfo():
res = requests.get(
"https://graph.facebook.com/v8.0/1583917368454739?access_token=EAAEzYsBi3oUBAHQQ9w7jSW95FcZBflMnib1cHUpf9eMBnuSvNcvvg31oKtIGoZA9kYtpq3OLMNSgY01ErgZA21PDRqdz7APrdZAXFJ9k43TnJXH8ZADb9Cjr2JEevZCdPpyTOpsZBvxE7RC63JjxZBr60iNQjWlfwwGBqdS2knhXBebpWGezrkg5WLRuBaUi3IdZBIBozQp1KMdDUmNWyR365")
res = json.loads(str(res.text))
return res
这里的含义就是获取用户id为1583917368454739的用户信息,访问:https://localhost:8000/getinfo/
用户信息轻松获取,更多的用户接口可以参照官方文档:https://developers.facebook.com/docs/graph-api/reference/user/
结语:FaceBook三方登录的流程并不复杂,本篇主要是结合Go lang的mkcert库来生成自签证书以及FastAPI作为后端服务来实现本地模拟登录,这样就无须每次都在线上生产环境进行测试了。最后奉上FastAPI的项目地址:https://gitee.com/QiHanXiBei/fastapi_blog
原文转载自「刘悦的技术博客」 https://v3u.cn/a_id_174
利用本地HTTPS模拟环境为FastAPI框架集成FaceBook社交三方登录的更多相关文章
- 利用Docker搭建本地https环境的完整步骤
利用Docker搭建本地https环境的完整步骤 这篇文章主要给大家介绍了关于如何利用Docker搭建本地https环境的完整步骤,文中通过示例代码将实现的步骤介绍的非常详细,对大家的学习或者工作具有 ...
- ningx配置本地https环境
由于项目改成了https访问,所以本地开发的时候也要通过https验证,避免页面发送http请求. 例如原来是这样访问:http://192.168.88.88:8080/ 或 http://loca ...
- 利用Telnet来模拟Http请求 有GET和POST两种
利用Telnet来模拟Http请求---访问百度. 1.打开"运行"->cmd进入命令环境: 2.输入"telnet www.baidu.c ...
- [转]利用Docker构建开发环境
利用Docker构建开发环境 Posted by makewonder on 2014 年 4 月 2 日 最近接触PAAS相关的知识,在研发过程中开始使用Docker搭建了自己完整的开发环境, ...
- Cygwin--unix/linux模拟环境
Cygwin是一个在windows平台上运行的类UNIX模拟环境,是cygnus solutions公司开发的自由软件(该公司开发了很多有用的工具,著名的还有eCos,不过现已被Redhat收购).它 ...
- require.js+backbone 使用r.js 在本地与生产环境 一键压缩的实现方式
require.js+backbone 使用r.js 在本地与生产环境 一键压缩的实现方式 时间:2017-07-03 17:18:11 阅读:210 评论:0 收藏:0 ...
- Win10配Theano环境和Keras框架
网络上有各种各样的win7 64bit安装theano的方法,我也试过好多,各种各样的问题.因为之前没了解过MinGw等东西,所以安装起来比较费劲,经过不断的尝试,最终我按照以下过程安装成功. 其实过 ...
- 利用Docker构建开发环境
最近接触PAAS相关的知识,在研发过程中开始使用Docker搭建了自己完整的开发环境,感觉生活在PAAS时代的程序员真是幸福,本文会简要介绍下Docker是什么,如何利用Docker来搭建自己的开发环 ...
- multipath多路径实验01-构建iscsi模拟环境
multipath多路径实验01-构建iscsi模拟环境 前几天跟同事网上闲聊技术,吐槽之前自己没有配置过多路径的经历,虽然多路径的配置过程很简单,职责划分也应是主机或存储工程师来搞定,DBA只需要直 ...
随机推荐
- 栈在go语言中实现,及解决388.文件的最长绝对路径的思路
今天在LeetCode刷每日一题,遇到了388. 文件的最长绝对路径的思路,这道题让我想到了系统的目录是栈结构,果然在题解中找到了栈的解法(暴力半天没出来,跑去看题解了QWQ). 所以我就捎带复习了一 ...
- 706. Design HashMap - LeetCode
Question 706. Design HashMap Solution 题目大意:构造一个hashmap 思路:讨个巧,只要求key是int,哈希函数选择f(x)=x,规定key最大为100000 ...
- Jwt隐藏大坑,通过源码帮你揭秘
前言 JWT是目前最为流行的接口认证方案之一,有关JWT协议的详细内容,请参考:https://jwt.io/introduction 今天分享一下在使用JWT在项目中遇到的一个问题,主要是一个协议的 ...
- [刷题] IDA*
BZOJ3041 水叮当的舞步 Description & Solution 见hzw的博客 http://hzwer.com/1507.html Code // Author: wlzhou ...
- 重学ES系列之函数优化
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- CentOS中实现基于Docker部署BI数据分析
作为一个专业小白,咱啥都不懂. linux不懂,docker不懂. 但是我还想要完成领导下达的任务:在linux中安装docker后部署数据可视化工具.作为一名敬业 的打工人摆烂不可以,躺平不可以,弱 ...
- 在mybatis中使用sum函数返回对象为Null
首先大家看一下我的XML中的SQL .DAO 和实体对象 XML DAO PO 乍一看 没毛病. 但是在Mybatis中使用sum函数,如果返回值是0(就是你在Navicat中运行的的sql正常,结 ...
- Redis开机自启
添加开机启动服务 vi /etc/systemd/system/redis.service 在redis.service中输入以下内容 ps:ExecStart配置成自己的路径 [Unit] Desc ...
- Codeforces Round #780 (Div. 3)
A. Vasya and Coins 题目链接 题目大意 Vasya 有 a 个 1-burle coin,有 b 个 2-burle coin,问他不能通过不找钱支付的价格的最小值. 思路 如果 a ...
- 最小生成树 链式前向星 Prim&Kruskal
Prim: Prim的思想是将任意节点作为根,再找出与之相邻的所有边(用一遍循环即可),再将新节点更新并以此节点作为根继续搜,维护一个数组:dis,作用为已用点到未用点的最短距离. 证明:Prim算法 ...