wolfiton

wolfiton

Nuxt SSR with phoenix http only cookies authenticate and authorize, is it possible?

Hello everyone,

I have the following stack that i am trying to make it work:

Backend:

  • Phoenix + Absinthe

Frontend

  • Nuxt

For this SSR app that I am working on(for learning purposes),I am trying to set a http only cookie and sent it towards NUXT, but i can’t find a reliable way to make NUXT work with the logic from the backend if the cookie is http only.

Also from the NUXT documentation on auth routes I figured that the default behavior doesn’t help me. Because it needs access to the cookie to read it and make decisions on authorization and authentication permissions.

The documentation wth examples of what i am talking about can be found here https://nuxtjs.org/examples/auth-routes/

So my learning has come to a stop and i would really like to move forward and finish this app with some of you may know is a medium clone(complex blog under MIT).

I am looking for solution to use SSR with http only cookies and couldn’t find anything, so please share any ideas or technologies that may help me to finish this.

Thank you in advance

First 10 of 20 Posts Switch mode

wolfiton

wolfiton OP

After a lot of search found this

https://github.com/nuxt-community/auth-module/issues/142

I am using an approach where I split my JWT into two cookies containing signature.payload and signature . The cookie containing signature is httpOnly and signature.payload can be accessed by the browser. This way I have the safety of httpOnly cookies while getting the user info in the payload and not risking of leaking the full JWT, as they are separated.
I think this is a reasonable and should be implemented. Meanwhile I guess I will have to write a custom solution

Can somone explain what is he referring too, when he says that is splitting the JWT singnature in 2 parts?

Because form the JWT docs I can’t understand it

Signature

To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

For example if you want to use the HMAC SHA256 algorithm, the signature will be created in the following way:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

The signature is used to verify the message wasn’t changed along the way, and, in the case of tokens signed with a private key, it can also verify that the sender of the JWT is who it says it is.

LostKobrakai

LostKobrakai

There are two parts to this: Authentication and Authorization.

The first is making sure someone else is who they claim to be. The second is about if someone is allowed to do a certain action.

Authentication is most important if you look at different parties. E.g. your client might need to authenticate for your server to trust it’s inputs. Now the question is does your nuxt app actually require authentication or do you only need to authenticate against a backend server? The nuxt app by itself hardly can do proper authentication, as the whole source is readable on the client so there’s not really a secret to authenticate a user by.

For authorization you could just send the nuxt app a list of permissions once authentication (probably by the server) is done and handle/modify however your app needs to handle it (timeouts or things like that).

This is basically what the person did with their JWT token. Put the part required for authentication in the httpOnly cookie and put the part for permissions in a js readable cookie, which now has nothing to do with authentication anymore, but is only meant for authorization.

wolfiton

wolfiton OP

Let me try to explain what i understood from your post:

So in the cookie with http only flag will contain only the user_id

and in the jwt will be the user_role?

LostKobrakai

LostKobrakai

The cookie will contain whatever you need for your server to maintain a session. In phoenix you can put the user_id on the cookie, because it’s signed and you can be sure it’s not changed if the signing secret is not compromised. But other systems just send e.g. a session ID and store actual data on the server or whatever. The key is that those cookies are to be kept httpOnly. It could also be a JWT stored in the cookie, but it doesn’t need to and imho there’s not much reason for it to be a JWT. For httpOnly cookies there’s no real benefit from a JWT over just Phoenix.Token.

For handing of data (permissions are also just data) to your nuxt app you need to use a transfer method, which is readable by js. Could be a normal cookie, could be an api request or anything the js in the end has access to.

Now you seem to be very cautious about security. With e.g. JWT and public key crypto (not shared secret) you could encode the permissions so the nuxt app can validate that the permissions came from your server, even though the private key is not on the client, only the public key would be. So you can be sure permissions are not altered since the server sent them.

What you cannot do however - without the server - is check if the permissions are current for the user, which is why usually JWTs are set to only be valid for small amounts of times. Your server has no way to actively revoke the permissions the JWT gives within your nuxt app once both are no longer connected.

Now it’s your turn to decide how rigidly you want to enforce authentication/authorization in your nuxt app. If the server is available you can always reauthenticate/ask for permissions of a user, but if that’s not the case you can just work with what you got from the server at earlier times. As mentioned prev. authentication just on the client without a server is not really secure. You need to make the decision what you allow the user to do in case the server is not available and maybe check authentication/authorization again when trying to send data to the server, once it’s available again.

andyjones11

andyjones11

Why not create an endpoint which returns information about the current user (it could be a “me” graphql query) that returns the current user plus roles if they have a valid cookie, or null if there is no user. You can call this endpoint at the top level of your app and pass the user and roles down to the lower level components on the frontend where needed.

Unless you have a very specific need to use JWTs then I think this is a much easier approach to use.

wolfiton

wolfiton OP

The problem is that when my app goes in pWA mode (offline first ) and i also have vuex that is used for the source of truth all the security patterns don’t match because if i store the jwt or cookie in the store I am vulnerable to all kind of attacks.

Can the me query be used to authorize page routes?

Ex:

me{
username
role
}

Then create a middleware for page authorization?

Because nuxt doesn’t have the route action beforeEnter from vue that would have been helpful here.

So i am getting confused on this part how to handle all this.

Also thank you for your help an explanations so far.

LostKobrakai

LostKobrakai

You’re not more attackable offline than you’re online, besides when it comes to sending data to your server. Everything, which your nuxt app loads/reads/displays can be accessed otherwise by people who can do javascript / open the dev tools or have otherwise access into the javascript runtime. Offline or not.

Sending data to the server is only possible when the app is not used offline anyways, so no problem here, let the server handle everything.

The only way for your nuxt app to prevent access to data is not storing it or at least deleting it once a certain timeout or other criteria is met. There’s no magical way to make data only readable by your application, but not someone with access to the runtime it works in. It’s as secure as your server is if you give someone ssh access to root.

wolfiton

wolfiton OP

So from what you shared with me now, I am better off using jwt with short life span of 5 minutes and make my PWA work even offline and for applications with sensitive data I should use phoenix and minimal JavaScript.

Thanks for the info and patience

LostKobrakai

LostKobrakai

You don’t even necessarily need the JWT. It’s just a way for your javascript to validate that a certain chunk for data was not altered since encoded by your server. This might be useful to your application or not.

Also authorization in javascript might still be useful if the risk of someone using e.g. the console to get to data is one you can take. Most often offline data is owned by the person using it, but you still like to not give data away to the random person strolling by their laptop. There are also ways in e.g. kiosk applications to show websites without giving people access to dev tools or alike.

If data is truely highly sensitive though it’s best kept on the server.

achempion

achempion

@wolfiton Hope you wouldn’t mind some off-topic question :slight_smile:

I’ve been exploring SSR frontend solutions for PWA for some time and I have concerns about them.

From hight point of view the idea is great, you can write SPA as SEO friendly fast-loading website but in details I heard about caveats with that approach.

The first is: You need the Node on the server to handle JS pre-rendering and you need to have a lot more memory to be able to process javascript on server side. Also it takes time to pre-render JS. Does it still able to answer within less than 1ms timeframe?

The second is: How well does it play with parallel requests? How many workers do you have which can work in parallel? As an example what I’m talking about: Low concurrent users cap with SSR · Issue #1840 · vercel/next.js · GitHub.

Thank you.

Where Next?

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
jonnycharles
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
silverdr
Using Phoenix.LiveView.TagEngine as an EEx.Engine is deprecated! To compile HEEx, use Phoenix.LiveView.TagEngine.compile/2 instead. Sta...
New
dli
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app? Looking for hints regarding: Addi...
New
bottlenecked
Hi all, I wanted to ask how the community is dealing with post-release steps. Today we have Ecto migrations, which make sure that the db...
New
michallepicki
I am using Oban and occasionally, shortly after a deployment, a handful of jobs can fail because of dependency on other parts of the syst...
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
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
type1fool
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
akoutmos
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New

We're in Beta

About us Mission Statement