I have a Vuejs application created using Nuxtjs. I am also using Django as the backend server, and I made an API to interact with the backend server (Django) and front-end app (Vuejs/Nuxtjs). And any API related fetch are done in the AsyncData function of the page to render the data on the server-side using axios. Also, I am using json web token authentication, and the API generates a jwt token after successful login which is stored in the cookie. So on the backend, it will always check for the request's authorization header for the token. If the request is from a logged in user (authorized token) then return authenticated json data, or else return non authenticated data.
_The problem:_
When the user navigates to the app, I would like to check if the user is authenticated. If the user is authenticated, render the authenticated page. If not then display non authenticated page.
_My thoughts:_
When the fetch is done from the App on the AsyncData function, I would check whether there is any value for the cookie. If there is then send the token with the request's authorization header. But, since the page will be rendered on the server first, and not on the client side (where the cookie actually is) it will never find the token for the authorization.
How can I check if the user is already logged in or not so that I can get authenticated and non authenticated data respectively from the API?
When the user navigates to the app, I would like to check if the user is authenticated. If the user is authenticated, render the authenticated page. If not then display non authenticated page.
You may use nuxt pages middleware for doing exact same job.
But, since the page will be rendered on the server first, and not on the client side (where the cookie actually is) it will never find the token for the authorization.
That's true. But one thing we may do is using req object which is available in server side to retrieve client side cookies and append them to axios Cookies.
Unfortunately, we still don't have a complete guide on SSR authentication but for second problem of having Cookies in server-side i recommend using axios-module it will do this automatically.
For the first problem, i also suggest taking a look at auth-module which integrates with axios for a complete solution. (You may also brow only some parts like auth middleware)
@Benjamin5050 I've been building Django + NuxtJS. I use Django https://github.com/GetBlimp/django-rest-framework-jwt to check token. In your case, you can use Middleware to do.
@pi0 Hi! I have checked out the nuxt-axios module, but I am still not clear. It does not tell how to retrieve cookie from the client side. When I successfully log in (post authorized email and password), I get a response back with the token, which I set in the cookie like this:
this.$cookie.set('my_auth_token', this.token, {expires: 15})
How can I retrieve client side cookie and add them to axios for SSR?
@feedgit Yes, I am also using django-rest-framework-jwt with django-rest-framework. How are managing the token between the client side and the nuxt server?
I'm using Rails as an API and Nuxt.js.
I have pretty much the same problem. Tokens are stored in the client side, fetch runs only the server side. The closest to a decent route authorization I managed to do is to check the cookie on page created. But it still displays the "protected" page content for a second before it is redirected to a login page.
Hi @Benjamin5050 and @samirph
I think the auth-module will help you solve the problem because it manage both SSR and client cookie registration, try to use all the attributes the library offers
I've seen that auth-module before.
This module uses axios for its requests, but my application is making only apollo requests.
Same issue, rails using devise-token-auth and nuxt for UI. On refresh the store is wiped clean in the browser and server, even with the suggestions above.
edit: I actually fixed this by ditching Devise all together and rolling my own stateless token solution. Nuxt auth module works great now.
We use django with REST framework JWT Auth combined with nuxtServerInit to achieve this. When a user logs in, the auth token gets set to the cookie. When nuxtServerInit runs, this token is extracted from the cookie and verified. It looks something like this:
export const mutations = {
setError (state, error) {
state.loginError = error
},
logout (state) {
Cookies.set('token', null)
Cookies.set('id', null)
state.user = null
},
setUser (state, { token, id }) {
Cookies.set('token', token)
state.user = { id }
}
}
export const actions = {
async nuxtServerInit ({ dispatch, commit }, { req }) {
if (req.headers.cookie) {
let { token } = cookie.parse(req.headers.cookie)
try {
var { data } = await axios.post(endpoint + '/auth/verify', { token })
if (data.token) {
commit('setUser', { token: data.token, id: data.id })
}
} catch (err) {
if (err.response.status === 400) {
commit('logout')
}
}
}
},
async login ({ commit }, { email, password }) {
try {
var { data } = await axios.post(endpoint + '/auth/login', { email, password })
await commit('setUser', {
token: data.token,
userId: data.id
})
} catch (err) {
if (err.response.status === 400) {
commit('setError', 'Invalid credentials')
}
}
}
}
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.