Linuus

Linuus

Hi!

(There may be some rubber ducking going on here but… anyway :slight_smile: )

I’m building a backend API for a mobile app and try to figure out a good way to handle the authentication. I’ve already setup the initial user registration using Comeonin etc. so now I’m trying to settle on some token format to use.

I found this: User authentication in Phoenix? but it’s more focused on regular web apps and not APIs.

A lot of people seem to use Guardian and JWTs.

Is there any reason to use a JWT over something like Phoenix.Token?

Both JWT and Phoenix.Token can be verified without having them stored in the DB, but that means that we can’t invalidate the tokens (without invalidating ALL tokens). Right? This feels a bit scary to me. Am I just overly cautious?

To solve this, you have two options (that I know of):

  • Use a short expiration time
    • In a mobile app, the user has to sign in often which is annoying.
  • Store the tokens in the DB and only tokens that are present among the user’s tokens are valid
    • Why use a JWT or Phoenix.Token if you still check them in the DB? You can just store a random string without data encoded in it or other complex features.
    • The DB will end up with a lot of stale tokens (may not be a big issue, but still)

What do you use on your APIs?
Why do you use that?

Showing Posts 21 to 30

minhajuddin

minhajuddin

  1. Using JWT tokens for browser sessions seems moot, because if you are storing a jwt token in the session you may as well store the user_id and make things simpler. If the session storage is cookie based, it is still safe because the cookies are signed and phoenix will blow up if you tamper the cookie.
  2. Using JWT tokens for API access seems reasonable, However, you don’t get the flexibility to invalidate them.
  3. Some people store the JWT token in a database and return another uuid which lets you look up the JWT token, this completely defeats the purpose of JWT.

Like the blog article linked above, I think JWT makes sense when you have 2 independent applications which need a way to authenticate without talking to each other. It makes more sense if you use public keys on sending server and the private keys on the receiving server for authentication.

karmajunkie

karmajunkie

In most cases, you’ll probably fetch the user from the database anyway, right? So, what’s the upside of this compared to just a raw token in the DB that you change on each logout/password reset etc?

If you make the assumption that every request is going to necessitate database interaction, particularly with a user account record, then yes, I don’t think it buys you anything. But examine that assumption. Why do we go to the DB for state on every request, even when it doesn’t change from one request to another?

What if instead the database was used to shadow the active state of your application? Your state is held in memory in genservers, and while writes are sent to the database, reads are independent of it. Read in the state to init the genserver, but not on every request. Then your transient bits of state like nonces/auth tokens can live in a more transient location.

Its certainly not the only way of doing it, and isn’t appropriate for every application. But particularly when web development has been steeped in the use of ORMs and the use of relational stores as an integration layer between applications and stateless servers, its worth reexamining the assumptions that we’ve gone with for nearly two decades in the face of alternatives which are just as viable, if less familiar.

riverrun

riverrun

I haven’t used eternal, so I can’t answer that question. Let me know how you get on and if you have any feedback.

riverrun

riverrun

You’re obviously right, and I know nothing. Do you feel any better now?

chu

chu

I don’t think he meant any disrespect to your work in any way by his comments.

Moving forward…
What is the best way to go about revoking jwt’s on pure API based applications serving mobile apps? Is there a right and wrong way or you probably go with what works even if that means “hitting the db” once in a while?

I believe security is fundamental and should not be an afterthought at the expense of being a purist. What are your thoughts?

chu

chu

If I am getting it correctly, this means it’s probably not a bad idea to throw in a db check in there if it allows you to validate and by extension secure your app ‘better’ :slight_smile:

Linuus

Linuus OP

Sorry if I offended you. It seems like you misunderstood me somehow. In my response in the last paragraph I meant “you” as in a general you, not you specifically. I have never looked at OpenMaize or anything you’ve done. I’m sure you are very knowledgeable and have good insights that would be beneficial for this discussion.

I have never used JWTs but I’m trying to learn more about them and the correct way to use JWTs. I think it’s important to understand and not just cargo cult.

Also, what I wrote are just statements that I’ve come to believe to be true about JWTs. I want them to be challenged. Please let me know if they are true or if I’m totally lost here. Any feedback is appreciated! :slight_smile:

riverrun

riverrun

The first question is whether you need to revoke the jwt at all - in many cases, it might be enough to just let it expire. With many apis, there isn’t really a logout functionality - the user will just access the resources he / she needs and then stop using it.
If you do want to revoke jwts, I know that many developers use Redis for this, and that might be quicker than a db lookup.
With openmaize_jwt, you can use the store_jwt(token) and query_jwt(token) functions in the OpenmaizeJWT.LogoutManager module to handle this.
If you have any further questions, please let me know.

riverrun

riverrun

It seems like there was a slight misunderstanding there :slight_smile:
To find out more about the differences between traditional cookie / session authentication and JWTs I think this link can explain it better than me. It’s important to know that the advantages might not be that relevant for you, depending on the nature of the app you’re writing. For example, the fact that you save a database lookup is meaningless if you’re then going to consult the database (to get more data) anyway. From my point of view, as an authentication library maintainer, it looks like JWTs are generally the more favored (future-proof?) option.
On the subject of logging out, the first thing that happens with most implementations is that the JWT is deleted - if it’s stored in a cookie, the JWT can be deleted on the backend, and if it’s stored in local storage, it needs to be deleted on the frontend. The next thing that some implementations do is try to guard against an attacker using the same JWT to gain access, by having some kind of blacklist and invalidating the JWT. This can be done by checking the database, and I know that some implementations use Redis to keep track of these JWTs. With Openmaize (and OpenmaizeJWT), I’m using a genserver to maintain this blacklist, and it is checked every hour and expired JWTs are removed, so it shouldn’t get too big (let me know if you want me to explain this in more detail).
The last thing to mention about logging out is that depending on the nature of your app, ‘logging out’ might not be that relevant - the user will just access the resources and then stop using them, after which the token will eventually expire (usually after 1-2 hours). There probably will still be a need for maintaining a blacklist, but in this case it would be for compromised JWTs.
If you have any further questions, just let me know.

swennemans

swennemans

Makes sense. I’m still experimenting with JWT. On Hackernews there are also some interesting discussion the last week.

For example: https://news.ycombinator.com/item?id=11929267

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
ryanwinchester
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted” Version...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews