IndominusByte / fastapi-jwt-auth

FastAPI extension that provides JWT Auth support (secure, easy to use, and lightweight)
http://indominusbyte.github.io/fastapi-jwt-auth/
MIT License
630 stars 143 forks source link

Invalid token type. Token must be a <class 'bytes'> #15

Closed NazarKostetskiy closed 3 years ago

NazarKostetskiy commented 3 years ago

Hi. I've got this problem. How to fix this?

Request to get access token: curl -H "Content-Type: application/json" -X POST -d '{"email":"test","password":"test"}' http://localhost:8000/login Response: {"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwiaWF0IjoxNjA0MzUwMTc4LCJuYmYiOjE2MDQzNTAxNzgsImp0aSI6IjI5Yjg3YTY0LTQyZDQtNGVlZC1iZmEyLTU4OTZhZjdhNjM2NiIsImV4cCI6MTYwNDM1MTA3OCwidHlwZSI6ImFjY2VzcyIsImZyZXNoIjpmYWxzZX0.o6JkaCJmANVbuwaj5loHmj_YBLfHchf8TiTssdwmgTM", "refresh_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwiaWF0IjoxNjA0MzUwMTc4LCJuYmYiOjE2MDQzNTAxNzgsImp0aSI6IjY5NTc1MjBhLTFiNDItNDFhOS1iMmRmLWZmNTU2ODBhNDIyYiIsImV4cCI6MTYwNjk0MjE3OCwidHlwZSI6InJlZnJlc2gifQ.SVa5ol5sDGzcUnDtrf--oduG5jifapXYy2zulwt6fO0"}

Request to protected endpoint with Authorize.jwt_required: curl -H "Authorization: Authorization-Token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwiaWF0IjoxNjA0MzUwMTc4LCJuYmYiOjE2MDQzNTAxNzgsImp0aSI6IjI5Yjg3YTY0LTQyZDQtNGVlZC1iZmEyLTU4OTZhZjdhNjM2NiIsImV4cCI6MTYwNDM1MTA3OCwidHlwZSI6ImFjY2VzcyIsImZyZXNoIjpmYWxzZX0.o6JkaCJmANVbuwaj5loHmj_YBLfHchf8TiTssdwmgTM" http://localhost:8000/protected Response: {"detail":"Invalid token type. Token must be a <class 'bytes'>"}

IndominusByte commented 3 years ago

its seem work to me, can you explain in more detail what code do you use and which version of fastapi-jwt-auth do you use 😁

NazarKostetskiy commented 3 years ago

its seem work to me, can you explain in more detail what code do you use and which version of fastapi-jwt-auth do you use grin

Yep. Tried on fastapi-jwt-auth==0.4.0 and 0.3.0. Routes:


router = APIRouter()

@router.post('/login')
async def login(user: UserScheme, Authorize: AuthJWT = Depends()):
    registered_user = User.get_one_obj({"email": user.email})
    if registered_user:
        print(registered_user)
        access_token = Authorize.create_access_token(subject=registered_user['email'])
        refresh_token = Authorize.create_refresh_token(subject=registered_user['email'])
        await app.state.redis.save_tokens(Authorize.get_jti(access_token), Authorize.get_jti(refresh_token))
        return {"access_token": access_token, "refresh_token": refresh_token}
    return {"result": False}

@router.get('/protected')
def protected(Authorize: AuthJWT = Depends()):
    Authorize.jwt_required()
    current_user = Authorize.get_jwt_subject()
    print(current_user)
    return {"status": "ok", "msg": "logged out"}

Settings:

@AuthJWT.token_in_denylist_loader
def check_if_token_in_denylist(decrypted_token):
    jti = AuthJWT().get_jti(decrypted_token)
    print(f"jti: {jti}")
    return app.state.redis.get_token(jti) is not None

@app.exception_handler(AuthJWTException)
def authjwt_exception_handler(request: Request, exc: AuthJWTException):
    return JSONResponse(
        status_code=exc.status_code,
        content={"detail": exc.message}
    )

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

class JwtSettings(BaseModel):
    authjwt_secret_key: str = JWT_SECRET
    authjwt_denylist_enabled: bool = True
    authjwt_header_type: str = 'Authorization-Token'
IndominusByte commented 3 years ago
@AuthJWT.token_in_denylist_loader
def check_if_token_in_denylist(decrypted_token):
    jti = AuthJWT().get_jti(decrypted_token) # you passing dictionary instead str of token
    # Its decrypted token, you can get JTI with this
    jti = decrypted_token['jti']
    print(f"jti: {jti}")
    return app.state.redis.get_token(jti) is not None
Screen Shot 2020-11-04 at 02 59 13

For detailed information, you can check the API documentation at token_in_denylist_loader(). Link 🙏

NazarKostetskiy commented 3 years ago
@AuthJWT.token_in_denylist_loader
def check_if_token_in_denylist(decrypted_token):
    jti = AuthJWT().get_jti(decrypted_token) # you passing dictionary instead str of token
    # Its decrypted token, you can get JTI with this
    jti = decrypted_token['jti']
    print(f"jti: {jti}")
    return app.state.redis.get_token(jti) is not None
Screen Shot 2020-11-04 at 02 59 13

For detailed information, you can check the API documentation at token_in_denylist_loader(). Link pray

My fault. Thanks for your explanation!