当前位置: 首页 > 知识库问答 >
问题:

从React读取Cookie(后端与FastAPI快速api-jwt-auth)

哈宪
2023-03-14

我在使用Axios和FastAPI理解Cookie中的JWT时遇到了一些问题。

我正在尝试用React作为前端,FastAPI作为后端,制作一个简单的应用程序。因为这更像是我的研究项目,所以我决定使用JWT进行身份验证,并将其存储在Cookie中。

身份验证流程非常基本。用户通过POST将凭证发送到后端,后端将JWT设置为Cookie并将其发送回。

我的问题是我无法读取返回前端的cookie。

现在,我知道你不能从Javascript中读取HttpOnly cookie,因此即使cookie是从登录请求设置的,我也无法从我的React应用程序中看到它们。

如果我使用失眠来检查登录API的行为,它工作正常,并设置了适当的cookie。

然而,我用于JWT身份验证的名为fastapi JWT auth的包通过Cookie发送CSRF令牌。这不仅仅是HTTPC。

因此,为了获取并使用我的CSRF令牌,我需要从React读取Cookie。我想我可以这么做,因为嘿,CSRF令牌不仅仅是HttpToken。但正如您从图像中看到的那样,标题中不存在set cookie

我假设这是因为从后端发送的cookie与HttpOnly cookie混合,而不是HttpOnly cookie。但是我不能从我的研究中证实这一点。

那么,我如何从响应中获得这个非HttpOnly cookie呢?或者这根本不可能?

这是我的示例项目。

package.json

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.9",
    "@testing-library/react": "^11.2.5",
    "@testing-library/user-event": "^12.8.0",
    "@types/jest": "^26.0.20",
    "@types/node": "^12.20.4",
    "@types/react": "^17.0.2",
    "@types/react-dom": "^17.0.1",
    "axios": "^0.21.1",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.3",
    "typescript": "^4.2.2",
    "web-vitals": "^1.1.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

src/App。tsx

import React, { useState } from "react";
import "./App.css";
import { authAPI } from "networking/api";

const App = () => {
    const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");

    const handleLogin = async () => {
        try {
            const response = await authAPI.login({ email, password });
            console.log(response);
            const cookies = response.headers["set-cookie"];
            console.log(cookies);
        } catch (err) {
            console.error(err);
        }
    };

    return (
        <div className="App">
            <input
                value={email}
                onChange={(event) => setEmail(event.target.value)}
                type="email"
            />
            <input
                value={password}
                onChange={(event) => setPassword(event.target.value)}
                type="password"
            />
            <button type="submit" onClick={handleLogin}>
                login
            </button>
        </div>
    );
};

export default App;

src/networking/api。ts

import axios from "axios";
import { Auth } from "models/auth";

const client = axios.create({
    baseURL: "http://localhost:8000/",
    responseType: "json",
    headers: {
        "Content-Type": "application/json",
    },
    withCredentials: true,
});

const auth = () => {
    return {
        async login(credential: Auth) {
            return await client.post("auth/login", credential);
        },
    };
};

const authAPI = auth();

export { authAPI };
export default client;

src/models/auth。ts

type Auth = {
    email: string;
    password: string;
};

export type { Auth };

Pipfile

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
fastapi = "*"
fastapi-jwt-auth = "*"
uvicorn = "*"

[dev-packages]

[requires]
python_version = "3.9"

main.py

import uuid

from fastapi import FastAPI, HTTPException, status, Body, Depends
from fastapi_jwt_auth import AuthJWT
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, BaseSettings
import uvicorn


app = FastAPI()


SECRET_KEY = '6qvsE3BBe7xvG4azL8Wwd3t_uVqXfFot6QRHIHZREkwrTZYnQHv6fSjInCB7'


class Settings(BaseSettings):
    authjwt_secret_key: str = SECRET_KEY
    authjwt_token_location: set = {'cookies'}
    authjwt_cookie_secure: bool = True
    authjwt_cookie_csrf_protect: bool = True
    authjwt_cookie_samesite: str = 'lax'


@AuthJWT.load_config
def get_config():
    return Settings()


CORS_ORIGINS = ["http://localhost:8080", "http://localhost:8000", "http://localhost:5000", "http://localhost:3000",]
app.add_middleware(
    CORSMiddleware,
    allow_origins=CORS_ORIGINS,
    allow_credentials=True,
    allow_methods=['*'],
    allow_headers=['*'],
)


class UserLoginIn(BaseModel):
    email: str
    password: str


@app.post('/auth/login')
async def login_user(user_in: UserLoginIn = Body(...), Authorize: AuthJWT = Depends()):
    try:
        user_id = str(uuid.uuid4())
        # create tokens
        access_token = Authorize.create_access_token(subject=user_id)
        refresh_token = Authorize.create_refresh_token(subject=user_id)
        # set cookies
        Authorize.set_access_cookies(access_token)
        Authorize.set_refresh_cookies(refresh_token)
    except Exception as err:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail='Failed Authorization.')
    return {'message': 'Successfully login'}


if __name__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=8000)

提前感谢您的任何见解:)

共有1个答案

任宾鸿
2023-03-14

对于会话,您应该只使用HttpOnly,因为它在JWT上的每次算法都几乎相同,JS可以读取CSRF cookie,因为它每次都会更改,并且您需要CSRF令牌来发送请求。

如何使用JavaScript读取HttpOnly cookie

 类似资料:
  • 问题内容: 我需要将包含4个字节整数(小尾数)的二进制文件读入我的Android应用程序的2D数组中。我当前的解决方案如下: 对于2k * 2k的阵列,这非常慢,大约需要25秒。我在DDMS中可以看到垃圾收集器正在加班,因此这可能是速度缓慢的原因之一。 必须有一种使用ByteBuffer将该文件读入数组的更有效的方法,但是目前我看不到它。关于如何加快速度的任何想法? 问题答案: 为什么不读入4字节

  • 我正在尝试在我的get函数上将我的rest api项目从烧瓶移动到FastAPI,我让获取所有过滤器变得非常容易,通过使用烧瓶,我使用了命令 其中< code>filter_name在我的对象上的所有字段之间改变,这就是我可以读取URL的方式,比如 http://127.0.0.1:8000/beers?过滤器[isbn]=72533 但是现在当我转向快速api时,我找不到像这样阅读url的方法。

  • 我有一些大型 netCDF 文件,其中包含 6 个分辨率为 0.5 度的地球每小时数据。 每年有360个纬度点,720个经度点和1420个时间点。我有年度文件(12 GB ea)和一个包含110年数据(1.3 TB)的文件存储为netCDF-4(这是1901年数据,1901.nc,其使用策略以及我开始使用的原始公共文件的示例)。 根据我的理解,从一个netCDF文件中读取应该比遍历最初提供的由年份

  • 可以通过document.cookie直接读取cookie的内容: var strCookie = document.cookie;  此时,strCookie是一个由该域名下的所有cookie的名/值对所组成的字符串,名/值对间以“分号加空格”分隔。为了方便查看,可以使用split()方法将cookie中的名/值对解析出来,得到一个cookie的列表。然后,再使用相应的解码方式,把cookie

  • 我最近在服务器上安装了一个React应用程序和一个单独的Node.js/express应用程序。我希望React应用程序能够从节点应用程序获取数据,但我不希望外部的任何人能够访问这些api调用,而不是从请求、直接链接、邮递员等访问。 起初,我考虑使用ExpressIPFilter只允许来自服务器的请求,但我想这不会起作用,因为请求通常来自用户ip!? 什么是使我的反应应用程序能够对其内容执行静态a

  • 本文向大家介绍JS设置cookie、读取cookie,包括了JS设置cookie、读取cookie的使用技巧和注意事项,需要的朋友参考一下 JavaScript是运行在客户端的脚本,因此一般是不能够设置Session的,因为Session是运行在服务器端的。 而cookie是运行在客户端的,所以可以用JS来设置cookie。 js设置cookie方法汇总: 第一种: 第二种: 第三个例子 注意: