Problem implementing nuxtjs/auth using local strategy - api

I'm following a nuxtjs tutorial and I'm having issues implementing nuxtjs/auth loginWith. It is pretty straightforward but I don't know why it doesn't work for me. tested with postman and the API responds with a token;
Everything looks okay, saves the token to cookies and local storage. Signup also works but it doesn't login. When I inspect with Vue dev tools, it shows login false and the user undefined when I'm expecting a user object. What could be wrong?
As it is, here's the method for Login.vue
async onLogin() {
try {
this.$auth.loginWith("local", {
data: {
email: this.email,
password: this.password
}
});
this.$router.push("/");
} catch (err) {
console.log(err);
}
}
here's also my nuxt.config.js
const URL = 'http://localhost:3000'
export default {
/*
** Nuxt rendering mode
** See https://nuxtjs.org/api/configuration-mode
*/
mode: 'universal',
/*
** Nuxt target
** See https://nuxtjs.org/api/configuration-target
*/
target: 'server',
/*
** Headers of the page
** See https://nuxtjs.org/api/configuration-head
*/
head: {
title: process.env.npm_package_name || '',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'stylesheet', href: '/css/font-awesome/css/all.css' },
{ rel: 'stylesheet', href: '/css/default.css' }
]
},
/*
** Global CSS
*/
css: [],
/*
** Plugins to load before mounting the App
** https://nuxtjs.org/guide/plugins
*/
plugins: [],
/*
** Auto import components
** See https://nuxtjs.org/api/configuration-components
*/
components: true,
/*
** Nuxt.js dev-modules
*/
buildModules: [],
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://bootstrap-vue.js.org
'bootstrap-vue/nuxt',
// Doc: https://axios.nuxtjs.org/usage
'#nuxtjs/axios',
'#nuxtjs/pwa',
'#nuxtjs/auth',
// Doc: https://github.com/nuxt/content
// '#nuxt/content',
],
/*
**Axios Module config
** See https://axios.nuxtjs.org/options
*/
axios: {
proxy: true,
baseURL: URL
},
proxy: {
"/api": URL
},
/*
** Build configuration
** See https://nuxtjs.org/api/configuration-build/
*/
build: {
extend(config, ctx) {}
},
auth: {
strategies: {
local: {
endpoints: {
login: {
url: "/api/auth/login",
method: "post",
propertyName: "token"
},
user: {
url: "/api/auth/user",
method: "get",
propertyName: "token"
},
logout: true
}
}
}
}
};

Try this:
auth: {
strategies: {
local: {
endpoints: {
login: {
url: "/api/auth/login",
method: "post",
propertyName: "data.token"
},
user: {
url: "/api/auth/user",
method: "get",
propertyName: "data.user"
},
logout: true
}
}
}
}
As the response from the api is received inside data, when axios is used.

Okay Somehow, it only updates the after I refresh the entire browser. I thought the Hot reloading would suffice but it works. this is my auth strategies setup
auth: {
strategies: {
local: {
endpoints: {
login: {
url: "/api/auth/login",
method: "post",
propertyName: "data.token"
},
user: {
url: "/api/auth/user",
method: "get",
propertyName: "data.user"
},
logout: true
}
}
}
}
Thanks to all that commented. It has helped my confidence and problem solving ability.

Related

#nuxt/auth send me to /login page when I reload the page or access URLs manually

I'm trying to implement a login system in my app (Nuxt 2) using #nuxt/auth. The backend is a Node.js + Express + Passport, using sessions and cookies.
I think it's important to say I'm using http-proxy-middleware in my front end, so my back end can be accessible in the same domain with localhost:3000/api/... or localhost:3000/uploads for uploaded files.
The backend seems to be working as expected, creating the sessions, returning an User object if logged in and 401 if not. I did some research and didn't find much advantages to use JWT so I opted for sessions and cookies instead (but any recommendations are valid). Cookies expiration time is set in the backend as 24 hours.
In my front end I don't have any custom middlewares.
In the front end, I can log in and it redirects me to home ('/'), and I can access protected pages, I have set auth globally but excluded from the login layout with auth: false.
But when I refresh the page or try to access some URL manually (e.g. /timeline) it goes back to the login page. I tried to show $auth.user in the login page and it's showing me the user's information as it was logged in. $auth.loggedIn is true.
One important thing to note is that it takes a while to show the information in $auth.user and $auth.loggedIn shows as false at the first second, maybe something to do with this? I checked the cookies and it seems to be all right, I will post more information below. (this in the login page)
When I tried to access my back end endpoint /api/user I get the user's information so I'm sure in my backend I'm logged in.
Also when I try to log out, at the first moment it logs me out but doesn't redirect to me to the login page. When I try to access some protected page it does redirect me as expected.
But I was expecting to not being redirected to login page when refreshing or accessing URLs manually, how can I fix this please?
This is my nuxt.config.js:
const { createProxyMiddleware } = require('http-proxy-middleware')
export default {
head: {
// ...
},
serverMiddleware: [
createProxyMiddleware('/api', {
target: 'http://localhost:3300/api',
changeOrigin: true,
pathRewrite: {
'^/api': '/'
}
}),
createProxyMiddleware('/uploads', {
target: 'http://localhost:3300',
changeOrigin: true,
pathRewrite: {
'^/uploads': '/uploads'
}
}),
],
router: {
middleware: ['auth']
},
// css: [],
css: [
'~assets/scss/main.scss',
],
// loading bar
loading: {
color: '#ef443b',
},
plugins: [
'~/plugins/vuelidate'
],
components: true,
buildModules: [
'#nuxtjs/eslint-module',
'#nuxtjs/style-resources',
'#nuxtjs/fontawesome',
],
modules: [
'bootstrap-vue/nuxt',
'#nuxtjs/axios',
'#nuxtjs/auth',
'nuxt-precompress',
],
auth: {
cookie: {
options: {
maxAge: 24 * 60 * 60 * 1000, // 24 hrs
secure: process.env.NODE_ENV && process.env.NODE_ENV === 'production', // HTTP if local, HTTPS if production
},
},
strategies: {
local: {
token: {
required: false,
type: false
},
endpoints: {
login: {
url: '/api/login',
method: 'POST',
propertyName: false
},
logout: {
url: '/api/logout',
method: 'GET'
},
user: {
url: '/api/user',
method: 'GET',
propertyName: false
},
},
tokenRequired: false,
// tokenType: 'Bearer',
},
},
},
bootstrapVue: {
bootstrapCSS: false, // Or `css: false`
bootstrapVueCSS: false // Or `bvCSS: false`
},
fontawesome: {
component: 'fa',
suffix: false,
icons: {
regular: true,
solid: true,
brands: true,
},
},
styleResources: {
scss: [
'./assets/scss/_variables.scss',
'./assets/scss/_mixins.scss',
],
hoistUseStatements: true,
},
axios: {
baseURL: '/',
withCredentials: true,
credentials: true,
},
env: {
apiUrl: process.env.API_URL,
},
publicRuntimeConfig: {
axios: {
browserBaseURL: process.env.BROWSER_BASE_URL
}
},
privateRuntimeConfig: {
axios: {
baseURL: process.env.BASE_URL
}
},
build: {
transpile: [
'audiomotion-analyzer'
]
},
}
My logout code is as simple as this:
methods: {
logout(e) {
this.$auth.logout()
},
},
These are the cookies when:
I log out and try to log in for the first time (maybe this cookie is from past sessions):
enter image description here
When I'm logged in and redirected to home:
enter image description here
When I access another protected page using a link:
enter image description here
When I try to access an URL manually and gets redirected to /login:
enter image description here
If necessary I can share some code from my backend too, but I think the problem is in my front-end...
EDIT
I just realized I was using this.$router.push('/') after logging in and had no config whatsoever for redirections, so I updated my nuxt.config.js and now it is redirecting without $router.push, and also when I log out. The refresh / manually access problem persists tho.
auth: {
cookie: {
options: {
maxAge: 24 * 60 * 60 * 1000, // 24 hrs
secure: process.env.NODE_ENV && process.env.NODE_ENV === 'production', // HTTP if local, HTTPS if production
},
},
strategies: {
local: {
token: {
required: false,
type: false
},
endpoints: {
login: {
url: '/api/login',
method: 'POST',
propertyName: false
},
logout: {
url: '/api/logout',
method: 'GET'
},
user: {
url: '/api/user',
method: 'GET',
propertyName: 'user'
},
},
tokenRequired: false,
// tokenType: 'Bearer',
},
},
redirect: {
login: '/login',
logout: '/login',
home: '/',
},
},

Nuxt.js Oauth sometimes crashes whole webpage

I have created Nuxt.js application, I decided to build in Nuxt/auth module, everything works fine in web browsers, but somethimes when user navigates with mobile browser my application is crushed, simply it don't respond nothing, also there is no api calls, but after one refresh everything works fine, I can not guess what's happening, I could not find anything in the resources available on the Internet.
const axios = require('axios')
export default {
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'app',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
],
script: [
// { src: "//code-eu1.jivosite.com/widget/UoBOrMfSmm", async: true },
]
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [ '~/assets/css/transition.css', '~/assets/css/errors.css' ],
pageTransition: "fade",
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
{ src: "~/plugins/star-rating", ssr: false },
{ src: "~/plugins/mask", ssr: false },
{ src: "~/plugins/rangeSlider", ssr: false },
{ src: "~/plugins/vueSelect", ssr: false },
{ src: "~/plugins/vuelidate", ssr: false },
],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
[ '#nuxtjs/google-analytics', {
id: 'xxx'
} ]
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/bootstrap
'bootstrap-vue/nuxt',
'#nuxtjs/axios',
'#nuxtjs/toast',
'#nuxtjs/auth-next',
[ 'nuxt-lazy-load', {
defaultImage: '/spin2.gif'
} ],
[ 'nuxt-facebook-pixel-module', {
/* module options */
track: 'PageView',
pixelId: '',
autoPageView: true,
disabled: false
} ],
'nuxt-moment',
'#nuxtjs/robots',
'#nuxtjs/sitemap'
],
moment: {
locales: ['ru', 'en']
},
toast: {
position: 'top-center',
},
robots: [
{
UserAgent: '*',
Disallow: ['/user', '/admin'],
},
],
axios: {
baseURL: 'https://api.test.com/', // Used as fallback if no runtime config is provided
},
sitemap:{
exclude:[
'/user',
'/admin',
'/admin/*',
'/user/*',
],
defaults: {
changefreq: 'daily',
priority: 1,
lastmod: new Date()
},
routes: async () => {
const { data } = await axios.get('https://api.test.com/api/cars/all')
return data.map((product) => `https://test.com/product/${product.id}/${product.name}`)
}
},
loading: {
color: '#F48245',
height: '4px'
},
target: 'server',
/* auth */
auth: {
plugins:[
{ src: "~/plugins/providers", ssr:false},
],
redirect: {
login: '/',
logout: '/',
home: '/',
callback: '/callback'
},
strategies: {
local: {
token: {
property: 'user.token',
},
user: {
property: false
},
endpoints: {
login: { url: 'api/login', method: 'post' },
logout: { url: 'api/logout', method: 'post' },
user: { url: 'api/user', method: 'get' }
},
},
facebook: {
endpoints: {
userInfo: 'https://graph.facebook.com/v6.0/me?fields=id,name,picture{url}',
},
redirectUri:'xxx',
clientId: '184551510189971',
scope: ['public_profile', 'email'],
},
google: {
responseType: 'token id_token',
codeChallengeMethod: '',
clientId: 'xxx',
redirectUri: 'https://test.com/callback',
scope: ['email'],
},
},
cookie: {
prefix: 'auth.',
},
},
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {},
};
This is my plugins directory file, where i am handling client oauth process.
export default async function ({ app }) {
console.log('auth executed')
if (!app.$auth.loggedIn) {
return
} else {
console.log('auth executed inside loop')
const auth = app.$auth;
const authStrategy = auth.strategy.name;
if (authStrategy === 'facebook') {
let data2 = {
fb_token: auth.user.id,
first_name: auth.user.name
}
try {
const response = await app.$axios.$post("/api/oauth", data2);
await auth.setStrategy('local');
await auth.strategy.token.set("Bearer " + response.user.token);
await auth.fetchUser();
} catch (e) {
console.log(e);
}
} else if (authStrategy === 'google') {
let dataGoogle = {
google_token: auth.user.sub,
first_name: auth.user.given_name,
last_name:auth.user.family_name
}
try {
const response = await app.$axios.$post("/api/oauth", dataGoogle);
await auth.setStrategy('local');
await auth.strategy.token.set("Bearer " + response.user.token);
await auth.fetchUser();
} catch (e) {
console.log(e);
}
}
}
}
For any issues related to DOM hydration, you can check my answer here: https://stackoverflow.com/a/67978474/8816585
It does have several possible cases (dynamic content with a difference between client side and server side rendered template, some random functions, purely wrong HTML structure etc...) and also a good blog article from Alex!

Why do I get this error only when my application is in production?

I am developing an application with NuxtJS and SSR, I am also using axios and auth modules. Everything works perfectly in localhost, but later when I upload the application to the host (Vercel) and try to log in, it gives me the 405 error. Does anyone know why this happens? The server is created with express
Error: Request failed with status code 405
at t.exports (237de42.js:2)
at t.exports (237de42.js:2)
at XMLHttpRequest._.onreadystatechange (237de42.js:2)
This is my nuxt.config.js file:
export default {
// Target: https://go.nuxtjs.dev/config-target
target: 'static',
ssr: true,
// Global page headers: https://go.nuxtjs.dev/config-head,
modules: [
'#nuxtjs/axios',
'#nuxtjs/auth-next',
'~/modules/api/index.js'
],
env:{
baseUrl: process.env.BASE_URL
},
axios: {
credentials: true,
https: true,
baseURL: 'https://www.encontrarhogar.com.ar/',
init(axios) {
axios.defaults.withCredentials = true
}
},
head: {
title: 'Encontrar Hogar',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'stylesheet', href: '/normalize.css' },
{ rel: 'stylesheet', href: "https://unpkg.com/swiper/swiper-bundle.min.css" }
],
script: [
{ src: "https://kit.fontawesome.com/57d52ad1ee.js", crossorigin: "anonymous" },
]
},
loading: {
color: 'black',
height: '8px',
continuous: true
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
'#/assets/css/index.css'
],
auth: {
strategies: {
local: {
token: {
property: 'token'
},
user: {
property: 'user'
},
endpoints: {
login: { url: '/server/api/usuarios/login', method: 'post', propertyName: 'data' },
user: { url: '/server/api/usuarios/mi-perfil', method: 'get', propertyName: 'data' },
logout: { url: '/server/api/usuarios/logout', method: 'delete' }
}
}
}
},
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: ['~/plugins/swiper.js'],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true
}

Why can't I create routes with parameters in my serverMiddleware in nuxt?

I'm having a problem configuring the serverMIddleware property, everything works perfectly, but I can't create any other route than the initial route
Mi nuxt.config.js file:
export default {
// Target: https://go.nuxtjs.dev/config-target
target: 'static',
ssr: true,
// Global page headers: https://go.nuxtjs.dev/config-head,
modules: [
'#nuxtjs/axios',
'#nuxtjs/auth-next',
// '~/modules/api/index.js'
],
serverMiddleware:[
{ path: '/api', handler: '~/api/index.js'},
],
axios: {
baseURL: 'http://localhost:3000/',
},
head: {
title: 'Encontrar Hogar',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: 'Encontra tu nuevo hogar en chacabuco. Todas las propiedades e inmuebles de Chacabuco en un mismo lugar' },
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'stylesheet', href: '/normalize.css' },
{ rel: 'stylesheet', href: "https://unpkg.com/swiper/swiper-bundle.min.css" }
],
script: [
{ src: "https://kit.fontawesome.com/57d52ad1ee.js", crossorigin: "anonymous" },
]
},
loading: {
color: 'black',
height: '8px',
continuous: true
},
css: [
'#/assets/css/index.css'
],
auth: {
cookie:{
options:{
secure: true
}
},
strategies: {
local: {
token: {
property: 'token'
},
user: {
property: 'user'
},
endpoints: {
login: { url: '/api/usuarios/login', method: 'post', propertyName: 'data' },
user: { url: '/api/usuarios/mi-perfil', method: 'get', propertyName: 'data' },
logout: false
}
}
}
},
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: ['~/plugins/swiper.js'],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true
}
/api/index.js file:
const bodyParser = require('body-parser')
const app = require('express')()
app.get('/api/:id?', (req, res) => res.send('hello'))
module.exports = app
If I try to create endpoints like the one that I will leave below, the only thing I get when making the get requests through the browser or postman is a 404 not found response, I do not understand what I am configuring wrong.
app.get('/api/products', (req, res) => res.send('products'))
Did you call http://localhost:3000/api/youridhere ?
According to your configuration and serveMiddleware, your link should be http://localhost:3000/api/api/youridhere
You have static target, change to "server" if you want serverMiddleware to work

NuxtJS Auth Proxy

Then using nuxtjs/auth and nuxtjs/axios nuxt is ignoring my proxy configuration.
In past I have used just axios for auth.
Now I am trying to use the #nuxtjs/auth module. Because I use a seperate backend and CORS I need to use axios proxy for auth.
But the auth stragegy local doesnt use the proxy and I dont get why. It always tries to use the nuxt URL. Seems like auth is absolutely ignoring my proxy. Can anyone help?
// nuxt.config
// ...
axios: {
proxy: true
},
proxy: {
'/api/': {
target: 'http://localhost:4000',
pathRewrite: { '^/api/': '' }
}
},
/*
** Auth Module Configuration
** See https://auth.nuxtjs.org/schemes/local.html
*/
auth: {
strategies: {
local: {
endpoints: {
login: { url: '/api/auth/login', method: 'post', propertyName: 'token' },
logout: { url: '/api/auth/logout', method: 'post' },
user: { url: '/api/auth/user', method: 'get', propertyName: 'user' }
}
}
}
},
// ..
// Component
async userLogin() {
try {
let response = await this.$auth.loginWith('local', { data: this.login })
console.log(response)
} catch (err) {
console.log(err)
}
}
My Nuxt is running on http://localhost:3000
My client always tries to connect to http://localhost:3000/api/auth/login
But I need http://localhost:4000/auth/login
I use all modules up to date
I have same problem. But I use #nuxtjs/auth-next because nuxtjs/auth is outdated and use #nuxtjs/proxy to replace nuxtjs/axios proxy.
Here is my pacakge dependencies.
// pacakge.json
"dependencies": {
"#nuxtjs/auth-next": "^5.0.0-1648802546.c9880dc",
"#nuxtjs/axios": "^5.13.6",
"#nuxtjs/proxy": "^2.1.0",
"nuxt": "^2.15.8",
// ...
}
Fixed nuxt.config.
// nuxt.config.ts
import type { NuxtConfig } from '#nuxt/types';
const config: NuxtConfig = {
ssr: false,
// ...ignore
modules: [
'#nuxtjs/axios',
'#nuxtjs/proxy',
'#nuxtjs/auth-next',
],
auth: {
strategies: {
local: {
name: 'local',
endpoints: {
login: { url: '/api/auth/login', method: 'post', propertyName: 'token' },
logout: { url: '/api/auth/logout', method: 'post' },
user: { url: '/api/auth/user', method: 'get', propertyName: 'user' }
}
// ...ignore
},
},
},
proxy: {
'/api': {
target: 'http://localhost:4000/',
secure: false,
// CORS problem need to set true,
changeOrigin: true,
pathRewrite: {
'^/api' : '/'
}
},
}
};
export default config;
If you set correct, when you run npm run dev the console should show below info.
[HPM] Proxy created: /api -> http://localhost:4000/
[HPM] Proxy rewrite rule created: "^/api" ~> "/"
[HPM] server close signal received: closing proxy server
The proxy object should be outside of the axios object, ie
axios: {
proxy: true,
// Your other configurations
}
proxy: {
'/api/': {
target: 'http://localhost:4000',
pathRewrite: { '^/api/': '' }
}
}