Learn-json-web-tokens: Translate Example to Elixir

Created on 25 Mar 2019  ·  4Comments  ·  Source: dwyl/learn-json-web-tokens

This tutorial is great for JavaScript but it would be _amaze_ to have it in Elixir from _first_ principals to _understand_ how to authenticate a request using JWT.

Todo

  • [ ] Investigate which JWT signing/verification package we can use in Elixir
  • [ ] Write a basic web server that requires a JWT Auth header to access a protected resource
    For a basic Elixir Web Server, see: https://github.com/dwyl/hits-elixir (no phoenix! 😮)
  • [ ] Tests!
  • [ ] write this up in a file called elixir-example.md

@RobStallion we briefly discussed this on the call today.
Please add any other acceptance criteria you feel are relevant.

enhancement help wanted technical

Most helpful comment

Have you had a read of: https://hexdocs.pm/plug/Plug.Session.COOKIE.html ? 💭

All 4 comments

@nelsonic I have been reviewing the code in /example to get a better understanding of how it works in order for me to recreate it in elixir.

I think I have understood the gist of what is happening for the most part.
You create a few routes in the server.js file and all the logic for these routes come from helper.js.

This is all straightforward enough to recreate in elixir (even without a phx server).

I have found a few packages/modules that are capable of creating JWTs in elixir. They are:

  • jose
  • joken (uses jose as a dep)
  • [guardian] (uses jose as a dep. More of an auth package than just a jwt)
  • yajwt (only has jason as a dep. Least used package mentioned and does not appear to be updated/maintained as often as the others.)

So far I have only used joken but it was fairly straightforward to create a JWT with it...

    {:ok, token, _} = LearnJwt.Token.generate_and_sign(%{user_id: 1})
    IO.inspect(token)

    LearnJwt.Token.verify_and_validate!(token)
    |> IO.inspect(label: "===> ")

logs....

"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJhdWQiOiJKb2tlbiIsImV4cCI6MTU1MzYzODYyMCwiaWF0IjoxNTUzNjMxNDIwLCJpc3MiOiJKb2tlbiIsImp0aSI6IjJtN3BuMnQ2MDBmMWN1Z3ZlazAwMDA1MyIsIm5iZiI6MTU1MzYzMTQyMH0.HQ-AQjvnIO7tIJF2joB45BJj7oLEznYSKUHZdMf9qe0"
===> : %{
  "aud" => "Joken",
  "exp" => 1553638620,
  "iat" => 1553631420,
  "iss" => "Joken",
  "jti" => "2m7pn2t600f1cugvek000053",
  "nbf" => 1553631420,
  "user_id" => 1
}

The verify_and_validate function also makes sure that the JWT has not been tampered with. If we create a JWT with the default secret and then try to decrypt it with a different secret we get an error...
config/dev.exs

config :joken,
  default_signer: "secret",
  testing: "test"

some_controller

    {:ok, token2, _} = LearnJwt.Token.generate_and_sign(%{user_id: 1}, :testing)
    LearnJwt.Token.verify_and_validate!(token2)

we get the following error...

image

This means that we can use these functions to create and verify our JWTs.

The part I am not entirely sure how to replicate is this, sending the JWT to the client.

I can send it to the client in the assigns argument of the render function like so...

render(conn, "index.html", jwt: token)

at which point we could store it in localStorage.

I haven't yet touched on how we will send the JWT back to the server but I assume that we can do this with js on the front end if there is not a "clean" way to do it using phoenix forms. (I have not seen one example of a phoenix application using phoenix templating to send jwt back to the server which leads me to think it is not "clean")

@RobStallion please _consider_ using https://hexdocs.pm/plug/Plug.Conn.html put_private/3 to save the JTW as auth_token. For an implementation example see: /lib/expected/plugs.ex#L88
LMK if you have want to walk+talk through it at any point this morning. 🤙

Have you had a read of: https://hexdocs.pm/plug/Plug.Session.COOKIE.html ? 💭

Taking a short break from this for now. Will come back to in a couple of days

Was this page helpful?
0 / 5 - 0 ratings

Related issues

KumarS-Naveen picture KumarS-Naveen  ·  3Comments

NE-SmallTown picture NE-SmallTown  ·  5Comments

nelsonic picture nelsonic  ·  5Comments

alanshaw picture alanshaw  ·  6Comments

joepie91 picture joepie91  ·  18Comments