Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Authentication with JWT

Authentication with JWT

Антон Егоров (Sabaka.io, CTO) @ Moscow Python Meetup 44

"Многие разработчики теряются, когда сталкиваются с таким, казалось бы простым, вопросом как авторизация. Все понятно, когда мы имеем дело с человеком на сайте, который вбивает свой логин и пароль. Но процедура становится в совсем другой, когда нужна аутентификация для API".

Видео: http://www.moscowpython.ru/meetup/44/authentication-with-jwt/

Moscow Python Meetup
PRO

April 20, 2017
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. Authentication with
    JSON Web Tokens
    by Anton Egorov
    April 2017

    View Slide

  2. Who am I?
    • Software Engineer with 10 years of experience
    • Working on Web and Mobile project
    • Scripting mostly with Python and JavaScript
    • CTO and Founder at sabaka.io

    View Slide

  3. Never heard about
    JWT before?

    View Slide

  4. It’s ok, no shame

    View Slide

  5. Alternatives you used
    before

    View Slide

  6. Cookie-based Auth
    POST /auth?user=…&pass=…
    Set-Cookie: session=…
    GET /api; Cookie: session=…
    HTTP OK
    new
    session
    find
    session
    Client
    app.example.com
    Server
    app.example.com

    View Slide

  7. Whats wrong with Cookies?
    • Cookies could be stolen and used for
    authentication until they expire some day
    • Its hard to invalidate sessions
    • You have to manage and scale session storage
    for your web servers
    • You have to configure CORS for your API
    requests if they are on a different domain

    View Slide

  8. Self-managed API keys
    • You can issue an manage some sort of API keys
    for your clients manually
    • You have to do everything from scratch:
    issuing, authorization, expiration, invalidation
    • You key will be just an authentication token

    View Slide

  9. There is a better way

    View Slide

  10. JSON Web Token
    • Three parts separated by dots: Header, Payload,
    Signature
    • Header typically has a token type and an algorithm
    being used (HMAC SHA256 or RSA)
    • Payload contains claims, reserved (iat, exp, nbf, iss,
    aud) and custom (e.g. name, email)
    • Signature is a concatenation of an encoded header
    and a payload plus a secret signed by an algorithm
    specified in the header

    View Slide

  11. Header
    {
    "alg": "HS256",
    "typ": "JWT"
    }
    eyJhbGciOiJIUzI1NiIsInR5
    cCI6IkpXVCJ9
    base64
    encode

    View Slide

  12. Payload
    {
    "exp": "1492714800000",
    "name": "Anton Egorov",
    "uid": "c2F0eXJpdXMK"
    }
    eyJuYW1lIjoiQW50b24gRWdvcm92Iiwi
    ZXhwIjoxNDkyNzE0ODAwMDAwLCJhZG1p
    biI6dHJ1ZX0
    base64
    encode

    View Slide

  13. Signature
    HMAC_SHA256(
    urlsafe_b64encode(header) + '.' +
    urlsafe_b64encode(payload),
    'my_secret'
    )
    x3kAwPPiHtO6YQLE4otr917BOvwYUY_L
    h7NKZQKaB6o
    base64
    encode

    View Slide

  14. Token
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpX
    VCJ9.eyJuYW1lIjoiQW50b24gRWdvcm9
    2IiwiZXhwIjoxNDkyNzE0ODAwMDAwLCJ
    hZG1pbiI6dHJ1ZX0.x3kAwPPiHtO6YQL
    E4otr917BOvwYUY_Lh7NKZQKaB6o

    View Slide

  15. PyJWT
    import jwt
    payload = {
    'exp': 1492714800000,
    'name': 'Anton Egorov',
    'uid': 'c2F0eXJpdXMK',
    }
    key = 'my_secret'
    jwt.encode(payload, key, algorithm='HS256')

    View Slide

  16. Application

    View Slide

  17. JWT-based Auth
    POST /auth?user=…&pass=…
    {"token": "eyJhbGciOi…"}
    GET /api; Authentication: eyJhbGciOi…
    HTTP OK
    new
    token
    validate
    token
    Client
    app.example.com
    Server
    api.example.com

    View Slide

  18. What’s the difference?
    • No Cookies means you don’t need to care
    about CORS and CSRF
    • Stateless, no session storage management
    • Mobile ready

    View Slide

  19. More advantages
    • Self-contained. The payload contains all the
    required information about the user.
    • Compact. Because of their smaller size, JWTs
    can be sent through a URL, POST parameter, or
    inside a HTTP header.
    • Secure. Information can be verified and trusted
    because it is cryptographically signed.

    View Slide

  20. Steps to implement
    • Endpoint to get a new JWT
    • Auth framework should accept Authentication
    header with JWT (e.g. create a middleware)
    • Take care of invalidation for long-live tokens

    View Slide

  21. Get ready for
    Production

    View Slide

  22. How to Secure JWT
    • Always verify the signature and claims (e.g
    exp) before you trust any information in the JWT.
    PyJWT does it for you by default.
    • Secure the secret signing key used for creating
    and verifying the signature
    • Do not put any sensitive data in a JWT
    • Use asymmetric encryption (RSA / ECDSA)

    View Slide

  23. Refresh token
    • Access tokens carry the necessary information
    to access a resource directly (short-lived)
    • Refresh tokens carry the information necessary
    to get a new access token (long-lived)
    • Refresh tokens improve security and allow for
    reduced latency

    View Slide

  24. Links
    • https://jwt.io
    • https://github.com/jpadilla/pyjwt
    • https://github.com/GetBlimp/django-rest-
    framework-jwt
    • https://github.com/jpadilla/django-jwt-auth
    • https://github.com/mattupstate/flask-jwt

    View Slide

  25. Questions?
    [email protected]

    View Slide