首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何验证作为HttpOnly cookie在FastAPI中发送的JWT?

如何验证作为HttpOnly cookie在FastAPI中发送的JWT?
EN

Stack Overflow用户
提问于 2022-11-30 22:36:11
回答 1查看 74关注 0票数 1

问题

我正在开发一个FastAPI应用程序,它需要对用户到达的某些端点进行身份验证。我正在使用Oauth2和FastAPI中的Jose创建用于身份验证过程的JWT。在进行了一些研究之后,确保令牌在前端受到保护的最佳方法似乎是将它们存储在HttpOnly Cookies中。我很难理解如何通过HttpOnly Cookies正确地传递JWT,以便我的FastAPI服务器能够在头中验证JWT。目前,当我尝试将JWT令牌作为HttpOnly Cookie传递时,我会得到一个401 Unauthorized Error

我试过的

当我将令牌作为模板字符串编码到标头中时,我已经能够使用JWT令牌成功地验证用户的身份。但是,当我将JWT作为Cookie通过头传递给FastAPI服务器时,我的FastAPI服务器无法对用户进行身份验证并返回401 unauthorized error。我试着查看网络选项卡,看看我向FastApi服务器的请求中发送了哪些标头,以便更好地理解这两种方案之间的不同之处。

成功的代码示例

当我将JWT作为模板字符串传递并获得200响应时,这是在标题中:

身份验证:承载令牌

代码语言:javascript
运行
复制
  async function getPosts() {
    const url = "http://localhost:8000/posts";
    const fetchConfig = {
      headers: {
        Authorization: `Bearer ${tokenValue}`,
      },
    };
    const response = await fetch(url, fetchConfig);
    const posts = await response.json();
  }

不成功的代码示例

当我将JWT作为一个HttpOnly Cookie传递并得到401响应时,这就是头文件中的内容:

Cookie: access_token="Bearer“

我还尝试更改了在服务器上设置cookie的方式,使标题看起来如下:

Cookie: Authentication="Bearer“

代码语言:javascript
运行
复制
  async function getPosts() {
    const url = "http://localhost:8000/posts";
    const fetchConfig = {
      credentials: "include",
    };
    const response = await fetch(url, fetchConfig);
    const posts = await response.json();
    console.log(posts);
  }

FastAPI码

下面是保护我的Oauth2端点的令牌验证的代码。这是基于FastAPI文档中的示例:FastApi Oauth2

代码语言:javascript
运行
复制
oauth2_scheme = OAuth2PasswordBearer(tokenUrl='login')

SECRET_KEY = settings.SECRET_KEY
ALGORITHM = settings.ALGORITHM
ACCESS_TOKEN_EXPIRE_MINUTES = settings.ACCESS_TOKEN_EXPIRE_MINUTES


def verify_access_token(token: str, credentials_exception):
  try:
    payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
    id: str = payload.get("user_id")
    if id is None:
      raise credentials_exception
    token_data = schemas.TokenData(id=id)
  
  except JWTError:
    raise credentials_exception

  return token_data

def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(database.get_db)):
  credentials_exception = HTTPException(
    status_code=status.HTTP_401_UNAUTHORIZED,
    detail=f"Could not validate credentials",
    headers={"WWW-Authenticate": "Bearer"}
  )

  token = verify_access_token(token, credentials_exception)
  user = db.query(models.User).filter(models.User.id == token.id).first()

  return user

下面是一个受保护端点的示例,它依赖于上面列出的get_current_user文件中的oauth2函数。

代码语言:javascript
运行
复制
@router.get("/", response_model=List[schemas.PostOut])
def get_posts(db: Session = Depends(get_db), current_user: int = Depends(oauth2.get_current_user):
  return {"Message": "Protected Endpoint Reached"}

我似乎遇到了这个问题,因为我的get_current_user函数在Oauth2中只有在以以下格式从标题中获取JWT:

身份验证:承载令牌

当令牌以下列任何一种格式存在时,它似乎无法从标头中验证令牌:

曲奇:access_token=“比勒令牌”Cookie: Authentication="Bearer令牌“

当我通过HttpOnly Cookies发送标头时,我是否需要以某种方式改变它们的发送方式,还是需要更改get_current_user函数的一些内容,从而使它能够正确地读取cookie头。

任何建议都是非常感谢的,并感谢您抽出时间阅读!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-12-01 06:57:41

要从cookie中获取令牌,而不是Authorization头( OAuth2PasswordBearer的缺省值),告诉FastAPI,您希望令牌来自cookie而不是

代码语言:javascript
运行
复制
def get_current_user(access_token: str = Cookie(...), db: Session = Depends(database.get_db)):

这假设令牌被命名为access_token (而不仅仅是令牌)。根据需要调整名称。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74634957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档