首页 > 其他分享 >How JWT (JSON Web Token) authentication works?

How JWT (JSON Web Token) authentication works?

时间:2022-11-10 23:22:07浏览次数:64  
标签:status Web self JWT token JSON key import

How JWT (JSON Web Token) authentication works?

https://www.idiotinside.com/2019/09/26/how-jwt-authentication-works/

What is JWT (JSON Web Token)?

JSON Web Token (JWT) is an open standard (RFC 7519) for securely transmitting information between parties as JSON object.

It is compact, readable and digitally signed using a private key/ or a public key pair by the Identity Provider(IdP). So the integrity and authenticity of the token can be verified by other parties involved.

The purpose of using JWT is not to hide data but to ensure the authenticity of the data. JWT is signed and encoded, not encrypted. 

JWT is a token based stateless authentication mechanism. Since it is a client-side based stateless session, server doesn’t have to completely rely on a datastore(database) to save session information.

 

How it works?

Basically the identity provider(IdP) generates a JWT certifying user identity and Resource server decodes and verifies the authenticity of the token using secret salt / public key.

  1. User sign-in using username and password or google/facebook.
  2. Authentication server verifies the credentials and issues a jwt signed using either a secret salt or a private key.
  3. User’s Client uses the JWT to access protected resources by passing the JWT in HTTP Authorization header.
  4. Resource server then verifies the authenticity of the token using the secret salt/ public key.

JWT

 

reference

https://jwt.io/introduction/

 

DEMO

https://github.com/amirhosss/FastAPI-RS256-MongoDB-Redis

私钥签发 token

https://github.com/amirhosss/FastAPI-RS256-MongoDB-Redis/blob/d3f484b542bb96be5d74b499a9f3ab586b77d4d1/core/security.py#L24

import uuid
from datetime import datetime, timedelta

from jose import jwt
from passlib.hash import bcrypt_sha256

from .config import settings


def get_password(password):
    return bcrypt_sha256.hash(password)


def verify_password(plain_password, hashed_password):
    return bcrypt_sha256.verify(plain_password, hashed_password)


with open('core/private_key.pem', 'rb') as private_file:
    private_key = private_file.read()
with open('core/public_key.pem', 'rb') as public_file:
    public_key = public_file.read()
    

def create_jwt_token(sub: str, aud: str, expires_delta: timedelta = None):
    expires_delta_condition = {
        'refresh': timedelta(days=settings.REFRESH_TOKEN_EXPIRE_DAYS),
        'access': timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES),
        'verification': timedelta(minutes=settings.VERIFICATION_TOKEN_EXPIRE_MINUTES)
    }

    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + expires_delta_condition[aud]

    to_encode = {'sub': sub, 'aud': aud, 'exp': expire, 'jti': str(uuid.uuid4())}
    encoded_jwt = jwt.encode(
        to_encode,
        private_key,
        algorithm=settings.JWT_TOKEN_ALGORITHM
    )
    return 

 

公钥验证和打开token

https://github.com/amirhosss/FastAPI-RS256-MongoDB-Redis/blob/master/api/dependencies/get_user.py

from typing import Optional

from fastapi import Depends, HTTPException, status, Cookie
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from pydantic.error_wrappers import ValidationError
from jose import jwt
from jose.exceptions import JWTError

import crud, models, schemas
from core.config import settings
from core.security import public_key
from utils.redis import redis

security = HTTPBearer(auto_error=settings.HTTP_BEARER_AUTO_ERROR)


class TokenRequired:
    def __init__(self, token_type) -> None:
        self.token_type = token_type

    def __call__(
        self,
        credentials: HTTPAuthorizationCredentials = Depends(security),
        access_token: Optional[str] = Cookie(None),
        refresh_token: Optional[str] = Cookie(None)

    ) -> Optional[str]:
        if credentials:
            return (token := credentials.credentials)
        elif access_token and self.token_type == 'access':
            return (token := access_token)
        elif refresh_token and self.token_type == 'refresh':
            return (token := refresh_token)
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail='Not authenticated',
            headers={'WWW-Authenticate': 'Bearer'}
        )


access_token_required = TokenRequired(token_type='access')
refresh_token_required = TokenRequired(token_type='refresh')


class GetUser:
    def __init__(self, token: str, audience: str) -> None:
        self.token = token
        self.audience = audience

    async def decode(self) -> None:
        try:
            payload = jwt.decode(
                self.token,
                public_key,
                algorithms=[settings.JWT_TOKEN_ALGORITHM],
                audience=self.audience
            )
            token_data = schemas.TokenPayload(**payload)
        except (JWTError, ValidationError):
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail='Could not validate credentials'
            )

        jti_status = await redis.get(str(token_data.jti))
        if jti_status and jti_status == 'true':
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail='Token is invalidated'
            )

        self.token_data = token_data

    async def get_current_user(self) -> models.User:
        await self.decode()
        user = await crud.user.read_by_id(self.token_data.sub)
        if not user:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail='User not found'
            )
        return user

 

标签:status,Web,self,JWT,token,JSON,key,import
From: https://www.cnblogs.com/lightsong/p/16879203.html

相关文章

  • OSGI开发web应用
    开发web的两种方式基于OSGI开发B/S应用有两种方式:1)在OSGI框架中嵌入Http服务器2)在Servlet容器中嵌入OSGI框架Http服务器嵌入到OSGI框架环境配置配置运行环境,选择Run->Run......
  • webpack与grunt、gulp的不同
    首先,它们的共同点三者都是前端构建工具,grunt和gulp早期比较流行,现在webpack是主流;区别:grunt和gulp基于任务和流;webpack基于入口文件,webpack会自动解析入口......
  • webpack中 ,有哪些常见的Loader?他们是解决什么问题的?
    1.css-loader翻译css,可以把sass/less代码翻译成css代码;2.imgage-loader加载并压缩图片文件3.source-map-loader加载额外的map文件,方便断点调试,但体积比较大......
  • 神操作 之 远程调试 WebView 定位加载缓慢的坑。。。
    甜的时候,甜到让人不敢相信。苦的时候,苦到让你日夜无眠。前言事情的缘由,因为老韩某天贱嗖嗖的说,来,你搜下那个课程,现在免费,原价好几百,请你看。ummm,原谅我的年少无知太单纯,......
  • webpack的构建流程是什么?从读取配置到输出文件这个过程尽量说全
    webpack的运行流程是一个串行的流程,从启动到结束会依次执行以下步骤;1.初始化参数:在配置文件,读取并合并参数,得到最终的参数;2.开始编译:拿着上一步的参数初始......
  • JavaWeb-05-Maven
    5.Maven为什么要学习这个技术?在javaweb开发中,需要使用大量的jar包,需要我们手动去导入;如何能够让一个东西自动帮我导入和配置这个jar包。因此,Maven诞生。5.1Maven架......
  • JavaWeb-02-web服务器
    2.web服务器2.1技术讲解ASP:微软:国内最早流行的就是ASP;在html中嵌入了VB的脚本ASP+COM;在ASP开发中,基本一个页面都有几千行的业务代码,页面及其混乱维护成本高C#I......
  • JavaWeb-04-Http
    4.http4.1http是什么超文本传输协议(HyperTextTransferProtocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以......
  • 处理Retrofit MalformedJsonException报错
    使用Retrofit配合GsonConverter,我们能很好地将网络响应内容转换成对应的对象。比如像下面这样。Retrofit网络接口方法publicinterfaceDroidNetwork{@GET("/content......
  • 说说关于Android使用Gson解析Json所需实体类的那些事~
    LZ-Says:技术,真的是日积月累,厚积薄发~前言目前解析json的方法有很多种,LZ个人认为使用Gson还是一种很不错的选择,因为使用Gson时,我们只需要考虑将json中参数和实体类属性一一对......