VueJS router.push() issue - vue.js

I'm going straight to the point here. I'm doing an authentication on the login page, after clicking the login page it redirects me to a product's component and on that product's component, I do an HTTP request to get all the products. However, after logging in and redirecting on the products page the product's component seems it can't run my HTTP request on the created() lifecycle hooks. Is this a normal behaviour?
Here's my code:
LOGIN:
export default{
data(){
return {
email: '',
password: ''
}
},
methods:{
login(){
var data = {
client_id: 2,
client_secret: 'TOKEN_HERE,
grant_type: 'password',
username: this.email,
password: this.password
}
this.$http.post("oauth/token", data).then(response => {
this.$auth.setToken(response.body.access_token, response.body.expires_in + Date.now())
this.$router.push('/products')
})
}
}
PRODUCTS.VUE
import Products from './product/Products.vue'
export default {
components: {
'my-products' : Products
},
created(){
this.$http.get('api/products')
.then(response => {
alert("products from feed");
this.products = response.body
})
}
}
after redirecting to products.vue created lifecycle hook, it can't run my http request.
Thanks in advance.

I seems like you need mounted hook instead.
https://v2.vuejs.org/v2/guide/instance.html#Instance-Lifecycle-Hooks

Related

how can i encode a token in my url using vuejs

i have an app which recieves token in my broswer url
http://localhost:8081/reset/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MmU2YWJmMmMzMzI0Mjk1NGQyNmVjZjIiLCJpYXQiOjE2NTk1MDIwNTEsImV4cCI6MTY1OTUwMjk1MX0.GIlKy_GI7HlfuB1WgD9HPxOGRZUX2_uOtOclrDTW3Y8
how can i remove (.) from my url
this is how i go to my route
{ name: "reset", path: "/reset/:token", component: Reset },
this is my script tag on how i call the function
<script>
import axios from "axios";
export default {
data() {
return {
password: "",
confirm_password: ""
};
},
mounted() {
console.log("the id is :" + this.$route.params.token);
},
methods: {
async submit() {
let token = this.$route.params.token;
let encoded = encodeURI(token);
return axios({
method: "post",
data: {
password: this.password,
token: this.$route.params.token
},
url: "http://localhost:5000/api/auth/updatePassword",
headers: {
"Content-Type": "application/json"
}
})
.then(res => {
console.log(res);
this.$router.push({ name: "login" });
})
.catch(error => {
console.log(error);
});
},
clear() {
this.$refs.form.reset();
}
}
};
</script>
i can't get the reset page until i remove the (.) please how can i encode the token
The token that you have is a JWT token, which should contain the two dots. I don't think removing them is a good idea. However, it looks like Vue router interprets the dots like a separator or something, causing the router to fail in finding the route.
What you might do is use a query string instead of a route param. You add the token to the url like:
http://localhost:8081/reset?token=eyJhbGciOiJ...
You should change the route to:
{ name: "reset", path: "/reset", component: Reset },
Now you can get it from the router with:
this.$route.query.token

How do I connect NuxtJS login auth to my backend with axios?

I currently have a frontend auth app somewhat made with NuxtJS, where it will take in username/password fields and then use this.$auth.login to login.
I'm confused, though, on how to pass this info to the backend so it can verify that the username/password combination is correct. Currently my code will direct to the next page no matter what I put in the fields (makes sense since I haven't configured anything yet). I understand I need to use Axios POST requests somehow and I made an attempt at that but I don't really know what to do next. I don't know how to grab the token that contains my user data and push it to my backend (adonisJS) so I can check it against the database.
My login.vue component
<template>
<div>
<v-form #submit.prevent="loginUser">
<div>
<v-label>Username</v-label>
<v-text-field color='red' v-model="login.username" />
</div>
<div>
<v-label>Password</v-label>
<v-text-field color='red' v-model="login.password" />
</div>
<div>
<v-btn type="submit" color='purple'>Submit</v-btn>
</div>
</v-form>
</div>
</template>
<script>
export default {
data() {
return {
login: {
username: '',
password: ''
}
}
},
methods: {
async loginUser() {
const response = await this.$axios.post("/auth/users", {
email: this.email,
password: this.password,
}).then(
await this.$auth.login({
data: {
email: this.email,
password: this.password
}
}).then(() => {
this.$router.push('/dashboard')
}).catch(err => {
console.log(err)
})
).catch(err => console.log(err));
}
}
}
</script>
My nuxt.js.config (relevant parts)
axios: {
baseURL: 'http://localhost:3000/api', // Used as fallback if no runtime config is provided
},
auth: {
strategies: {
local: {
token: {
property: 'access_token',
required: true,
type: 'Bearer'
},
user: {
property: false, // <--- Default "user"
autoFetch: true
},
endpoints: {
login: { url: '/auth/login', method: 'post' },
logout: { url: '/auth/logout', method: 'post' },
user: { url: '/user', method: 'get' }
}
}
}
},
router: {
middleware: ['auth']
},
Can anyone help me out with what I need to do with axios? (I checked my storage to see if there was a token there and it just says "false".) Thank you!
You don't need to use axios post, this is how you should log in
methods: {
async loginUser() {
try {
//this will attempt to log in, and if successful it'll go to the home page unless you change the default redirects
const fields = {email: this.email, password: this.password};
await this.$auth.loginWith("local", { data: fields });
console.log("login successful");
} catch (errors) {
//an error occurred, could be wrong password or any other type of error
console.error(errors);
}
}
}
local is the strategy name and means that it's your own auth server, if you were using google for example you'd put google there, check out loginwith and local
the auth library already knows that your login url is /auth/login since you stated that in the nuxt config.
if you want to control where it goes after the login, look into the redirect options in the nuxt.config from the docs and specifically in this case home.
auth: {
redirect: {
home: '/'
}
}

How to get user info after a successful authentication with nuxt-auth

I'm using nuxt.js, after I send a login request with email and password to the backend I get a response which contains a message, token and user informations, how can I access user informations in the response and save it inside some state in store.js after a successful login?
I wanted to save user object in user state down in store/index.js using an action saveUserAction which might be dispatched after a successful login, i dont know if thats right or not, any advise would be very helpful
Response
{
"message":"success",
"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiNzFkYjA1MWM2MTYxMmE4YzAyNWI2YjU3N2xMzJiNzJjMjI0MzRlY2IzNzYwNTg2N2NjOWQ5ZWEwY2MiMJM3uYEiZ8GSlPlQhIctVErO2KzwXOBxifWWoM7et_qT-mgvfsk3ljwiQF9iPQw-WeekBx8J8lcmxDLESa3tfE1Re1Xk2flkcBLmiI4JN2YHh08U1U",
"user":{
"id":1,
"role_id":4587,
"firstname":"Hans",
"lastname":"newman",
"email":"newman#gmail.com",
"email_verified_at":null,
"phone":"89498",
"skype":"gdgdfg",
"birthdate":"2021-05-02",
"address":"asdfaf",
"postalcode":14984,
"city":"jisf",
"country":"isfisf",
"status":"mfof",
"created_at":"2021-06-16T09:33:08.000000Z",
"updated_at":"2021-06-16T09:39:41.000000Z",
"image":"1623835988-carlsen.png",
"description":"sfdgg",
"geo_lat":5.5,
"geo_lng":8.1
}
}
login.vue
<script>
import { mapActions } from 'vuex'
export default {
data() {
return {
auth: false,
email: '',
password: '',
}
},
methods: {
async login() {
const succesfulLogin = await this.$auth.loginWith('local', {
data: {
email: this.email,
password: this.password,
},
})
if (succesfulLogin) {
await this.$auth.setUser({
email: this.email,
password: this.password,
})
this.$router.push('/profile')
}
},
},
}
</script>
store/index.js
export const state = () => ({
user:{}
})
export const mutations = {
saveUser(state, payload) {
state.user=payload;
}
}
export const actions = {
saveUserAction({commit}, UserObject){
commit('saveUser');
}
}
Go to your vue devtools, vuex tab and look for auth, it should already be available. This answer may help you during your debugging: https://stackoverflow.com/a/68081536/8816585
Since you do have your user object in the response, this kind of configuration should do it, as shown in the documentation. No need to make some other vuex actions.
auth: {
strategies: {
local: {
token: {
property: 'token',
global: true,
},
user: {
property: 'user', // the name of your object in your backend response payload
},
endpoints: {
[...]
}
}
}
}

this.$auth.loggedIn returning false

I'm using laravel/passport for authentication in the backend and nuxtjs as frontend when I send a login request from nuxtjs, in case login success, I get back as a response a token and user informations and then the user will be redirected to /profile page, however in /profile page when I return this.$auth.loggedIn I'm getting false!
login.vue
<script>
export default {
data() {
return {
auth: false,
email: "",
password:""
}
},
methods: {
async login() {
try {
const data = { email: this.email, password: this.password }
await this.$auth.loginWith('local', { data:data})
.then(() => this.$router.push('/profile'))
} catch (e) {
}
}
}
}
</script>
profile.vue
<template>
<div class="mt-6">loggedInUser: {{ loggedInUser }}</div>
</template>
<script>
export default{
data() {
return {
loggedInUser:this.$auth.loggedIn
}
}
}
nuxt.config.js
auth: {
strategies: {
provider: 'laravel/passport',
local: {
user: {
property: false,
autoFetch: true
},
endpoints: {
login: { url: '/login', method: 'post', propertyName: 'token' },
user: { url: '/user', method: 'get' }
},
clientId: 'cleint_id',
clientSecret: 'client_secret'
}
}
},
modules: [
'#nuxtjs/axios',
// https://go.nuxtjs.dev/bootstrap
'bootstrap-vue/nuxt',
'#nuxtjs/auth',
],
axios: {
baseURL: "http://prostudent.test/api"
},
and how nuxt knows that a user is logged in since logging in happens in the backend?
this is directly after I click on login, I get redirected to profile and the response of login is as expected, message, token and infos, but in /profile page seems like I'm not logged in!
Even if you're not using Vuex with your own modules, nuxt/auth creates some state for you. Hence the the presence of this.$store.state.auth.loggedIn. Btw, did you tried appending $store on your profile.vue file? As shown in the documentation.
Like this
<template>
<div class="mt-6">
loggedInUser: {{ $store.state.auth.loggedIn }}
</div>
</template>
Also, open your vue devtools and check the vuex tab, you'll find some nice state there.
This also answers your other question
and how nuxt knows that a user is logged in since logging in happens in the backend?
Nuxt checks the response from the server and depending of it, sets the state of auth.loggedIn to either true or false.
Those are the 2 steps that you need to do to achieve a successful login (use loginWith + setUser).
const succesfulLogin = await this.$auth.loginWith('local', {
data: {
email: this.email,
password: this.password,
},
})
if (succesfulLogin) {
await this.$auth.setUser({
email: this.email,
password: this.password,
})
}
After those, loggedIn may pass to true.
Of course, the user info can be fetched from the backend too. Depends of your use case.
Use a computed property instead of data property :
<template>
<div class="mt-6">loggedInUser: {{ loggedInUser }}</div>
</template>
<script>
export default{
computed: {
loggedInUser(){
return this.$auth.loggedIn
}
}
}

How to redirect to login if not authenticated in Vue with DRF

I'm working with vue and django rest framework, and what I want to do is validate if I don't have a token in my localStorage (not login) redirect to login page.
Here my component code in my login.vue:
<script>
import axios from 'axios'
import swal from 'sweetalert'
export default {
data () {
return {
username: '',
password: '',
token: localStorage.getItem('user-token') || null
}
},
methods: {
login() {
axios.post('http://localhost:8000/auth/', {
username: this.username,
password: this.password,
})
.then(resp => {
this.token = resp.data.token;
localStorage.setItem('user-token', resp.data.token)
this.$router.push('/atentusianos')
})
.catch(err => {
localStorage.removeItem('user-token')
swal("Credenciales Incorrectas", "", "error")
})
}
}
}
</script>
If the authentication is correct, i get my token from my localStorage like this:
...
methods: {
getAtentusianos(){
let axiosConfig = {
headers: {
'Authorization': 'Token ' + this.token
}
}
const path = 'http://localhost:8000/atentusianos/'
axios.get(path, axiosConfig).then((response) => {
this.atentusianos = response.data
})
.catch((error) => {
console.log(error)
})
}
},
created(){
let token;
this.token = TokenService.getToken()
this.getAtentusianos()
}...
I need help please...
You can do this in your Vue Router beforeEach guard. This runs on every route before directing to the requested page, including on a new page load or refresh, so it's ideal for handling this type of logged in check.
router.beforeEach((to, from, next) => {
const token = localStorage.getItem('user-token')
// If logged in, or going to the Login page.
if (token || to.name === 'Login') {
// Continue to page.
next()
} else {
// Not logged in, redirect to login.
next({name: 'Login'})
}
}
});
Note: this code assumes your login route name is Login, so you can update that accordingly.
I also recommend using VueX to get and store your auth token, and your default value for the token in your store can be from local storage or a cookie. That just makes it more efficient, checking the Vuex store value instead of getting it from local storage or the cookie every time.
Vue Router navigation guards: https://router.vuejs.org/guide/advanced/navigation-guards.html