• JWT JSON WEB TOKEN


    JWT

    https://jwt.io/introduction

    是一套开放的标准,定义了在两者之前安全传输信息的方法,信息的内容为JSON格式。

    What is JSON Web Token?

    JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

    Although JWTs can be encrypted to also provide secrecy between parties, we will focus on signed tokens. Signed tokens can verify the integrity of the claims contained within it, while encrypted tokens hide those claims from other parties. When tokens are signed using public/private key pairs, the signature also certifies that only the party holding the private key is the one that signed it.

    两种使用场景:

    • 授权
    • 信息传输

    When should you use JSON Web Tokens?

    Here are some scenarios where JSON Web Tokens are useful:

    • Authorization: This is the most common scenario for using JWT. Once the user is logged in, each subsequent request will include the JWT, allowing the user to access routes, services, and resources that are permitted with that token. Single Sign On is a feature that widely uses JWT nowadays, because of its small overhead and its ability to be easily used across different domains.

    • Information Exchange: JSON Web Tokens are a good way of securely transmitting information between parties. Because JWTs can be signed—for example, using public/private key pairs—you can be sure the senders are who they say they are. Additionally, as the signature is calculated using the header and the payload, you can also verify that the content hasn't been tampered with.

    payload属性名缩写

    https://www.iana.org/assignments/jwt/jwt.xhtml

    ss Issuer [IESG] [RFC7519, Section 4.1.1]
    sub Subject [IESG] [RFC7519, Section 4.1.2]
    aud Audience [IESG] [RFC7519, Section 4.1.3]
    exp Expiration Time [IESG] [RFC7519, Section 4.1.4]
    nbf Not Before [IESG] [RFC7519, Section 4.1.5]
    iat Issued At [IESG] [RFC7519, Section 4.1.6]
    jti JWT ID [IESG] [RFC7519, Section 4.1.7]
    name Full name

    JWT Authentication in FastAPI

    https://www.freecodecamp.org/news/how-to-add-jwt-authentication-in-fastapi/

    https://github.com/mabdullahadeel/fcc-fastapi-jwt

    登录,生成jwt token,返回给客户端。

    from fastapi import FastAPI, status, HTTPException, Depends
    from fastapi.security import OAuth2PasswordRequestForm
    from fastapi.responses import RedirectResponse
    from app.schemas import UserOut, UserAuth, TokenSchema
    from replit import db
    from app.utils import (
        get_hashed_password,
        create_access_token,
        create_refresh_token,
        verify_password
    )
    from uuid import uuid4
    
    @app.post('/login', summary="Create access and refresh tokens for user", response_model=TokenSchema)
    async def login(form_data: OAuth2PasswordRequestForm = Depends()):
        user = db.get(form_data.username, None)
        if user is None:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Incorrect email or password"
            )
    
        hashed_pass = user['password']
        if not verify_password(form_data.password, hashed_pass):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Incorrect email or password"
            )
        
        return {
            "access_token": create_access_token(user['email']),
            "refresh_token": create_refresh_token(user['email']),
        }
    def create_access_token(subject: Union[str, Any], expires_delta: int = None) -> str:
        if expires_delta is not None:
            expires_delta = datetime.utcnow() + expires_delta
        else:
            expires_delta = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
        
        to_encode = {"exp": expires_delta, "sub": str(subject)}
        encoded_jwt = jwt.encode(to_encode, JWT_SECRET_KEY, ALGORITHM)
        return encoded_jwt

    权限限制资源,对token进行验证

    from app.deps import get_current_user
    
    @app.get('/me', summary='Get details of currently logged in user', response_model=UserOut)
    async def get_me(user: User = Depends(get_current_user)):
        return user

    get user 验证token

    from typing import Union, Any
    from datetime import datetime
    from fastapi import Depends, HTTPException, status
    from fastapi.security import OAuth2PasswordBearer
    from .utils import (
        ALGORITHM,
        JWT_SECRET_KEY
    )
    
    from jose import jwt
    from pydantic import ValidationError
    from app.schemas import TokenPayload, SystemUser
    from replit import db
    
    reuseable_oauth = OAuth2PasswordBearer(
        tokenUrl="/login",
        scheme_name="JWT"
    )
    
    
    async def get_current_user(token: str = Depends(reuseable_oauth)) -> SystemUser:
        try:
            payload = jwt.decode(
                token, JWT_SECRET_KEY, algorithms=[ALGORITHM]
            )
            token_data = TokenPayload(**payload)
            
            if datetime.fromtimestamp(token_data.exp) < datetime.now():
                raise HTTPException(
                    status_code = status.HTTP_401_UNAUTHORIZED,
                    detail="Token expired",
                    headers={"WWW-Authenticate": "Bearer"},
                )
        except(jwt.JWTError, ValidationError):
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="Could not validate credentials",
                headers={"WWW-Authenticate": "Bearer"},
            )
            
        user: Union[dict[str, Any], None] = db.get(token_data.sub, None)
        
        
        if user is None:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Could not find user",
            )
        
        return SystemUser(**user)

    flowchart compared to cookie

    FASTAPI 项目模板也是用JWT

    https://github.com/tiangolo/full-stack-fastapi-postgresql/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/backend/app/app/api/api_v1/endpoints/login.py

    @router.post("/login/access-token", response_model=schemas.Token)
    def login_access_token(
        db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()
    ) -> Any:
        """
        OAuth2 compatible token login, get an access token for future requests
        """
        user = crud.user.authenticate(
            db, email=form_data.username, password=form_data.password
        )
        if not user:
            raise HTTPException(status_code=400, detail="Incorrect email or password")
        elif not crud.user.is_active(user):
            raise HTTPException(status_code=400, detail="Inactive user")
        access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
        return {
            "access_token": security.create_access_token(
                user.id, expires_delta=access_token_expires
            ),
            "token_type": "bearer",
        }

    SSO JWT

    https://dzone.com/articles/securing-spring-boot-microservices-with-json-web-t

    三种角色

    token刷新

    https://code-maze.com/using-refresh-tokens-in-asp-net-core-authentication/

    https://sarwiki.informatik.hu-berlin.de/Zugriffskontrolle_(SSO,JWT,SAML,XACML)

    认证授权

    auth2认证授权

    https://www.yht7.com/news/107169

    https://testdriven.io/blog/oauth-python/

    在认证服务器上产生token后, 此token在资源服务器上进行校验,校验方式是通过共享的secret完成的, 这里共享是 认证服务器 和 资源服务器。

  • 相关阅读:
    PHP开发者的MySQL错误
    shell编程技术和实例《linux0.01内核分析与操作系统设计》
    函数问题1 init_EMUX
    sizeof问题
    C语言读书心得
    《深入浅出MFC》读书感受
    计算机专业学习多年的苦恼
    一个完整的字符设备驱动程序导读
    学习书籍选择
    鼠标滑动、文本添加(倒计时)
  • 原文地址:https://www.cnblogs.com/lightsong/p/16695533.html
Copyright © 2020-2023  润新知