使用pyhon+django实现Https环境FaceBook(脸书)三方登录
使用pyhon+django实现Https环境FaceBook(脸书)三方登录
前言:
一些国际的软件/网站支持的比较多的第三方登录是Google第三方登录、Facebook第三方登录等。这里记录下Facebook第三方登录的过程。下面是一个Facebook第三方登录流程示例:
- 用户点击Facebook登录按钮,客户端(App、Browser等)向Facebook发起请求,用户在Facebook的页面输入登录信息(用户名、密码……),登录成功后Facebook回调客户端并带回用户的Facebook信息
- 客户端把用户登录Facebook的token发送至服务端,服务端调Facebook的token验证接口验证token是否有效
- 如果有效,至此Facebook第三方登录就成功了。
\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\)
开发步骤
Facebook应用配置
- 在 https://developers.facebook.com 开通Facebook开发者账号
- 创建应用
- 配置相关参数,在这里把AppId(应用编号)和AppSecret(应用秘钥)记下来。
1.添加产品
登录成功之后可以看到控制台打印出了登录成功后Facebook返回的信息,有accessToken、userID等:
可以添加Android、IOS、web页面等类型的授权登录
2.配置回调地址。
这里以网页版的授权为例,如果开发网页版的Facebook授权登录,需要在Facebook后台配置有效OAuth跳转URI,就是用户在Facebook登录页面登录成功之后需要回调到部署你自己的登录页面的服务器地址。
这里需要注意的是,FaceBook官方对安全性要求很高,它要求三方的应用强制使用HTTPS协议,而一般情况下本地环境的解决方案就是使用自签证书,所以这里使用一种更加简单友好的方式生成本地https证书,并且信任自签CA的方案——mkcert。
mkcert是一个使用go语言编写的生成本地自签证书的小程序,具有跨平台,使用简单,支持多域名,自动信任CA等一系列方便的特性可供本地开发时快速创建https环境使用。
安装方式也非常简单,由于Go lang的静态编译和跨平台的特性,官方提供各平台预编译的版本,直接下载到本地,给可执行权限(Linux/Unix需要)就可以了。Github地址:https://github.com/FiloSottile/mkcert
\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\)
【choco 安装】chocolatey 安装步骤包管理工具参考博客:
https://blog.csdn.net/weixin_41000111/article/details/81942660
注意
:powershell win10电脑都是有的 win键+R 输入powershell 就可以启动了
windows10上使用mkcert:
https://blog.csdn.net/qq_34924407/article/details/99707227
\(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\)
如果是Win10平台,可以使用Chocolatey来安装:
choco install mkcert
Mac os平台则可以使用Homebrew,非常方便:
brew install mkcert
安装成功之后,运行命令将CA证书加入本地可信CA:
mkcert -install
在Win10的可信CA列表可以找到该证书:
- 查看win信任的证书办法机构:https://www.cnblogs.com/andy9468/p/10110465.html
同理在Mac OS的证书列表同样也可以找到:
- 接下来我们就可以生成自签证书了,比如本地通过localhost或者127.0.0.1来访问你的web应用:
在终端中输入:
mkcert localhost 127.0.0.1 ::1
会自动生成:
C:\Users\admin>mkcert localhost 127.0.0.1 ::1
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" ✅
It will expire on 20 March 2023 🗓
可以看到成功生成了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作为登录页面:
授权登录sdk,Facebook官方提供了详细的说明,也有现成的sdk和完整的demo。
官方文档: https://developers.facebook.com/docs/facebook-login/web
<html>
<head>
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v6.0&appId=746492673568696&autoLogAppEvents=1"></script>
<script>
function login() {
FB.login(function(response){
console.log(response);
});
}
</script>
</head>
<body>
<h1>Facebook登录</h1>
<!-- 自定义登录按钮 -->
<button id="loginBtn" οnclick="login();" >登录</button>
</body>
</html>
登录页面中需要将代码里的appid改为你自己的自建应用的id。
将login.html放入到FastAPI项目的static目录,随后访问它:https://localhost:8000/static/login.html
点击登陆按钮, 如果登录成功,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/
最后我们就可以得到一个用户名和用户id
用户信息轻松获取,更多的用户接口可以参照官方文档:https://developers.facebook.com/docs/graph-api/reference/user/
可以参考技术大神FastAPI的项目地址:https://gitee.com/QiHanXiBei/fastapi_blog
https://blog.csdn.net/pyf09/article/details/109223865