Token based authentication from phx_gen_auth

After the great work done in phx_gen_auth, I was wondering if it would be possible to modify phx_gen_auth to support --no-html to generate a token based authentication instead of the session based authentication. (Support --no-html · Issue #38 · aaronrenner/phx_gen_auth · GitHub)

I started a little draft (Auth api by StephaneRob · Pull Request #1 · StephaneRob/mix_phx_gen_api_auth_demo · GitHub) from a new phoenix application where I generated the session based authentication with phx_gen_auth, and tried to convert it to a token based authentication.

But as there is a lot work to adapt the generator (and certainly out of the scope of phx_gen_auth), I would like to know if there is a need/interest for a dedicated generator?

The session based authentication works with tokens. Can you give a little more precision?

1 Like

Usually You do not treat authentification for an API the same as You would for a full Phoenix project.

For an API it is common to add a token in the header for each request. It is then decoded into auth info server side…

It is not the same, but You can use plug to solve both, except the authentication is managed differently.

But I have not really tried phx_gen_auth, just once… and it did install controllers, templates and views. This is not required for a JSON API.

2 Likes

Yes, my idea was to adapt the generator to remove templates files, and return json instead. On login a token is returned with other information like user email.

The main difference is that this token need to be sent for each request by the front application, and need to be fetch in the authorization header by the server.

The remember me cookie is used as refresh cookie to refresh the session via the /users/me enpoint to allow the front application to fetch an access token.

Not really. It has been since long discouraged to store the token in local-/sessionStorage (xss attacks).
I have a project based on Absinthe/GraphQL and cookies work just fine.

It is better to compare the means of transport of the token, i.e. localStorage+HTTP header VS Cookie.
“Session vs token” makes little sense to me.

If you still need to add the token in the header, I’d like to know why. Cross domain requests?

2 Likes

If you use cookies you’re still likely in a “webapplication using the api” context and less likely in a mobile app or even server to server type communication context. For the latter there’s neither xss nor csrf possibility if I understand those correctly. Your suggestion is certainly correct for a web context, but that’s not all the things interacting with apis.

4 Likes

@LostKobrakai, yes it’s exactly the use case I’m interested in. Be able to consume an API easily from different devices.

@thojanssens1 agree that it’s discouraged to store token in local/session storage. The token returned by the API should be kept in memory (react context, redux state, vuex…).

In memory in a js context is just as unsafe to xss attacks as local/session storage. Anything accessable to js is prone to such attacks. The only save solution is a http(s)_only cookie, which can’t be read by the js runtime.

5 Likes

I think that it’s not really as unsafe as local/session storage, because the token doesn’t stay in the browser.
The refresh cookie is stored as http_only cookie.

If your js runtime has access to your token so has an attacker exploiting an xss vulnerability.

1 Like

You’re right ! the only safe place would be an http only cookie.

1 Like

In my humble opinion, this seems essential to phx_gen_auth if it is to become part of the standard Phoenix framework. A lot of people use Phoenix just for their API, so a lot of people will want to be able to do:

mix phx.new --no-html --gen-auth  # I don't know what the actual flag will be
1 Like

It already is merged in to phoenix and it’s still a valid tool even if limited to session based authentication with logins – especially given how much more diverse, with various different tradeoffs, authentication for api’s is.

1 Like

I didn’t know it was already merged. I agree it’s still a valid tool.

I’m often puzzled at the dismissal for APIs and their technologies in this forum. I’ve seen multiple API authentication questions be shot down immediately here: “JWT is unsafe”, “tokens are unsafe”… That’s understandable, but we have to authenticate our single page apps somehow, and people use tokens.

It’s the difference between theory and pragmatism.

As someone who’s new to Elixir and Phoenix, it’s incredibly off-putting and a shame considering how suitable Phoenix is for the task of building APIs. It’s a pleasure.

3 Likes

It’s not about token, it’s about JWT versus Phoenix Token…

It’s not about Phoenix API, it’s about API in general :slight_smile:

And I agree Phoenix is really nice to build API.

Thanks for the clarification, it’s just been a little frustrating as someone new to the community who’s been trying to implement an auth solution for API use.

I’ve seen tons of questions spiral into theoretical debates and not get solved, and I wish that wasn’t the case, because it can be very difficult for beginners like me to find up-to-date information and pointers.

I’ll likely be writing a tutorial sometime on implementing API auth, once I get a little bit better at Phoenix and Elixir :slight_smile:

And yes, Phoenix rocks for API development. It’s a pleasure.

1 Like

The problem is how people use jwt for authentication, it’s not really done for that.

http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/

Nothing related to Phoenix, except we can use Phoenix Token instead as they are lighter than jwt.

5 Likes

Thank you for the pointers. What solution can we use for API centric/SPA development?

Do Phoenix tokens store information like user ID securely, to easily use it in a Plug?

Thanks!

It stores whatever You want…

The only difference is Phoenix Token cannot be decrypted client side, while JWT can be.