📜  使用 FastAPI 和 ReactJS 的服务器端 Google 身份验证

📅  最后修改于: 2022-05-13 01:54:25.983000             🧑  作者: Mango

使用 FastAPI 和 ReactJS 的服务器端 Google 身份验证

FastAPI 是一个现代、快速的 Web 框架,用于使用Python构建 API,而 react 是一个 javascript 库,可用于开发单页应用程序。所以在这篇文章中,我们将讨论使用 FastAPI 和 Reactjs 的服务器端身份验证,我们还将设置会话。

首先,如果你在Python中创建一个虚拟环境来保持我们的依赖项与其他项目分开会更好。为此,请安装一个虚拟环境并激活它。您可以参考这篇文章或在 Internet 上阅读相关内容。

在继续之前,请在谷歌云控制台上创建一个项目。在我们的例子中,授权的 JavaScript 源是 http://localhost:3000,授权的重定向 URI 是 http://localhost:3000/auth/google/callback。

因此,对于身份验证,我们将使用 google auth 并接收 ID 令牌,ID 令牌将被传输到后端,然后后端将验证它是否有效。如果它是有效的,那么我们将设置会话,否则请求将被拒绝。

让我们先从后端设置开始:

  1. pip install fastapi:用于REST接口调用常用函数实现应用。
  2. pip install itsdangerous:允许您使用登录序列化程序来加密和解密 cookie 令牌。
  3. pip install uvicorn:用于 ASGI 服务器。
  4. pip install google-auth:用于Python的 Google 身份验证库。
  5. pip install requests:用于在Python中发出 HTTP 请求。

我们将为后端使用端口 8000,为前端部分使用 3000。应添加允许的来源以避免 cors 错误。在我们的例子中,它是“http://localhost:3000”

现在我们的下一步将是创建身份验证 API 端点以接收 ID 令牌。然后调用verify_oauth2_token函数,传递ID token和clientID进行验证。如果请求成功,则设置会话。例如,我们在会话 cookie 中添加了一个电子邮件 ID。

Python
from typing import Optional
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from starlette.requests import Request
from starlette.middleware.sessions import SessionMiddleware
import uvicorn
  
  
from google.oauth2 import id_token
from google.auth.transport import requests
  
app = FastAPI()
  
origins = [
    "http://localhost:3000",
]
  
app.add_middleware(SessionMiddleware ,secret_key='maihoonjiyan')
  
  
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
  
@app.get("/auth")
def authentication(request: Request,token:str):
    try:
        # Specify the CLIENT_ID of the app that accesses the backend:
        user =id_token.verify_oauth2_token(token, requests.Request(), "116988546-2a283t6anvr0.apps.googleusercontent.com")
  
        request.session['user'] = dict({
            "email" : user["email"] 
        })
          
        return user['name'] + ' Logged In successfully'
  
    except ValueError:
        return "unauthorized"
  
@app.get('/')
def check(request:Request):
    return "hi "+ str(request.session.get('user')['email'])
  
if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)


Javascript
import GoogleLogin from 'react-google-login';
  
const responseGoogle = (response) => {
    if (response.tokenId){
      fetch('http://localhost:8000/auth?token='+ response.tokenId,{
        credentials: 'include',
        // To cause browsers to send a request with credentials included on both same-origin and cross-origin calls, 
        // add credentials: 'include' to the init object you pass to the fetch() method.
       })
      .then((response) => {
        return response.json();
      })
      .then((myJson) => {
        alert(myJson)
      });
    }
}
  
const temp = () =>{
  fetch('http://localhost:8000',{
    credentials:'include' 
  })
  .then((response) => {
    return response.json();
  })
  .then((myJson) => {
    alert(myJson)
  });
}
  
function App() {
  return (
    
                 
             
  ); }


后端服务器已准备好运行Python filename.py ,为前端创建一个反应应用程序

npx create-react-app my-app
cd my-app
npm start

现在再次安装一个 npm 包npm i react-google-login并添加 google 登录按钮和提要客户端 ID。然后连同令牌一起向后端发出请求。请添加凭据:'include'否则 cookie 将不会与您在成功验证后提出的任何请求共享。

Javascript

import GoogleLogin from 'react-google-login';
  
const responseGoogle = (response) => {
    if (response.tokenId){
      fetch('http://localhost:8000/auth?token='+ response.tokenId,{
        credentials: 'include',
        // To cause browsers to send a request with credentials included on both same-origin and cross-origin calls, 
        // add credentials: 'include' to the init object you pass to the fetch() method.
       })
      .then((response) => {
        return response.json();
      })
      .then((myJson) => {
        alert(myJson)
      });
    }
}
  
const temp = () =>{
  fetch('http://localhost:8000',{
    credentials:'include' 
  })
  .then((response) => {
    return response.json();
  })
  .then((myJson) => {
    alert(myJson)
  });
}
  
function App() {
  return (
    
                 
             
  ); }

这里的检查会话按钮用于检查身份验证后是否设置了cookie。

在此处查看整个应用程序的完整代码。