Im new to VueJS and trying to build authorization functions for my website.
First I attempt to use library name Vue-auth to handle authorization. It works fine, here is my code:
Login.vue
login () {
var redirect = this.$auth.redirect()
this.$auth.login({
headers: {
'Content-Type': 'application/json'
},
data: this.data.body,
rememberMe: this.data.rememberMe,
redirect: {name: redirect ? redirect.from.name : 'Home'},
success (res) {
console.log('Auth Success')
},
error (err) {
console.log(err)
}
navbar ():
<div class="nav-right is-flex">
<router-link v-if="!$auth.check()" to="/login" class="nav-item">Login</router-link>
<a v-if="$auth.check()" #click="logout" class="nav-item">Logout</a>
</div>
In router, to restrict access, I use auth property. Something like:
{
path: '/users',
name: 'users',
component: require('./components/pages/Users.vue'),
meta: {auth: ['admin']}
},
{
path: '/users',
name: 'users',
component: require('./components/pages/Users.vue'),
meta: true
}
And in app.js:
Vue.use(VueAuth, {
auth: {
request: function (req, token) {
this.options.http._setHeaders.call(this, req, {Authorization: 'Bearer ' + token})
},
response: function (res) {
// Get Token from response body
return res.data
}
},
http: require('#websanova/vue-auth/drivers/http/axios.1.x.js'),
router: require('#websanova/vue-auth/drivers/router/vue-router.2.x.js'),
loginData: { url: 'http://localhost:6789/login', fetchUser: false },
refreshData: { enabled: false }
})
But now I want to write a service to call axios to API Url myself, not using $auth.login function anymore. I changed my
login () {
var self = this;
_AuthenticationService
.login(this.data.body)
.then(response => {
self.info = response;
console.log(response);
})
.catch(err => {
self.info = err;
});
My service:
import axiosconfigurator from '../axiosconfigurator'
class AuthenticationService {
login (request) {
var self = this
return new Promise((resolve, reject) => {
axios.post('https://reqres.in/api/login', {
username: 'Fred',
password: '123'
})
.then(function (response) {
// get token from this response
var token = response.data.token
self._setAuthToken(token, true)
console.log(token)
// var data = core.Parsers.UserParser.parse(response);
// history.update(data);
// deferred.resolve(history);
})
.catch(function (error) {
console.log(error)
reject(error)
});
})
}
So my question is: I dont want to use the vue-auth library login function anymore, but I still want use its advantages like $auth.ready function, or auth property in router and $auth.user. How can I achieve it?
Based on the date of your question and the fact that the library was changed lately
You can call the login method on the vue-auth object passing the following option
makeRequest:false
You have a solution described there
https://github.com/websanova/vue-auth/issues/256
this.$auth.watch.authenticated = true
this.$auth.watch.loaded = true
this.$user(response.user)
this.$router.push('/dashboard')
I tested it and it was not working so I open a ticket
https://github.com/websanova/vue-auth/issues/563
Related
I'm having difficulties to understand how Shall I handle this type of calls. I need an initial axios.get call and loop through to make an axios.all call. This is my code:
export async function getServerSideProps(context) {
const axios = require("axios");
const options = {
method: 'GET',
url: 'xxxxx',
params: { id_user: 'xxxxx' },
headers: {
'X-RapidAPI-Host': 'xxxxxxx',
'X-RapidAPI-Key': 'xxxxxxx'
}
};
const res = axios.request(options).then(function (response) {
axios.all(response.data.users.map(user => {
axios.get('xxxxxxx', {
params: { response_type: 'short', ig: user.username, corsEnabled: 'true' },
headers: {
'X-RapidAPI-Host': 'xxxxx',
'X-RapidAPI-Key': 'xxxxxxx'
}
})
})).then(res => {
return res.data
})
})
const payload = await res;
I have an error on the page when I try to console log the payload. What's going worng with my call?
Looks like you need a return inside your map.
The below code worked for me and the unique params were updated on each request. Once you prepare your series of endpoints or whatever is unique for each request (user data per your sample code) you map over the relevant data and make all your get requests. The result returned will be an array of the responses you get back from each request once all of the requests have finished.
Regarding chaining together requests, you can use any number of .then() to kick off other actions. You mention needing an id from an initial get request, so here is a solution based on that example.
Hope you find it helpful.
const users = [{ username: '1' }, { username: '2' }, { username: '3' }];
axios
.get('https://jsonplaceholder.typicode.com/posts')
.then((res) => {
console.log(res);
// simulating getting some id you need...
const id = res.data[4].id;
console.log(id);
return id;
})
.then((id) => {
axios
.all(
users.map((user) => {
return axios.get('https://jsonplaceholder.typicode.com/posts', {
params: {
response_type: 'short',
// just an example of using id...
importantId: id,
ig: user.username,
corsEnabled: 'true',
},
headers: {
'X-RapidAPI-Host': 'xxxxxxx',
'X-RapidAPI-Key': 'xxxxxxx',
},
});
})
)
.then((res) => {
console.log(res);
});
});
i'm building an app with user login and register info. I use nuxt/auth module for handling the authentification. Whenever the user get logs in the state changes to true without a problem. The only issue i'm having is when i call set user method , the user info get registered successfully, but whenever i refresh the browser i lose the user data even though in the first place it was set successfully.
my nuxt.js config for nuxt auth module
auth: {
strategies: {
local: {
token: {
property: "token",
global: true,
},
redirect: {
"login": "/account/login",
"logout": "/",
"home": "/page/ajouter-produit",
"callback": false
},
endpoints: {
login: { url: "http://localhost:5000/login", method: "post" },
logout: false, // we don't have an endpoint for our logout in our API and we just remove the token from localstorage
user:false
}
}
}
},
My register/login component
async typeForm(e) {
this.typesubmit = true;
// stop here if form is invalid
this.$v.$touch();
if (this.$v.typeform.$anyError) {
return;
}
const user = await axios.post(`${baseUrl}register`,{
username:this.typeform.username,
password:this.typeform.password,
email:this.typeform.email,
tel:this.typeform.tel,
adresse:this.typeform.adresse,
store:this.typeform.store,
})
.then(response => {
console.log(response.data)
return response.data.user;
}).catch( (error) => {
this.error = ''
this.error = error.response.data
})
if(user){
let loginData = {email:this.typeform.email, password:this.typeform.password}
const response = await this.$auth.loginWith('local', { data: loginData})
.then(response => {
this.$auth.setUser(response.data.user) // the user is set without a problem, everything works fine.
return response.data;
}).catch( (error) => {
this.errors = error.response.data
console.log(error.response)
})
}
}
When i console log the state and the user in the first place everything works fine
console.log(this.$store.state.auth.user) // logs all user data i get from the api call. but when i refresh i get an empty object
console.log(this.$store.state.auth.loggedIn) // logs true , and even after i refresh it's still true
please help
Problem solved. what i did is to add to my login function
this.$auth.$storage.setUniversal('user', response.data.user, true)
works like a charm.
I have the samie issue.
After added this.$auth.$storage.setUniversal('user', response.data.user, true), the user is logged out after refreshing the page.
Here is my code :
this.$auth
.loginWith("local", {
data: {
email: this.connexionLogin,
password: this.connexionPassword
}
})
.then( (response) => {
this.$auth.setUser(response.data.user);
this.$auth.$storage.setUniversal('user', response.data.user, true)
this.$emit("connexionOk");
and my nuxt.config :
auth: {
watchLoggedIn: true,
resetOnError: true,
redirect: {
login: "/admin/login",
logout: "/admin/login",
callback: "/callback",
home: '/admin/', // Pour ne pas ĂȘtre redirigĂ© vers la home suite authentification
},
strategies: {
local: {
token: {
property: "tokens.access.token",
},
user: {
property: 'user',
autoFetch: false
},
endpoints: {
login: {
url: "v1/auth/login",
method: "post",
},
logout: false,
},
},
},
},
I am writing code to call api using axios. So, for this code I have to send an otp to the api along with an authorization token. I am using vuex store.
I am getting an error of 406(not applicable). This is the code I have written.
import { isAuthenticated } from './auth'
import axios from 'axios'
export default ({
state: {
},
mutations: {
},
getters: {
},
actions: {
VERIFY: (payload) => {
const userId = isAuthenticated().user._id
return axios
.post(apilink, payload, {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${isAuthenticated().token}`,
Accept: 'application/json'
}
}).then(response => {
console.log(response)
return response.data
})
.catch(error => {
if (error) {
console.log(error)
}
})
}
},
modules: {
}
})
<template>
<mdb-btn color="info" #click="verify()">Verify</mdb-btn>
</template>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js">
data () {
return {
value: ''
}
},
methods: {
verify () {
this.$store.dispatch('VERIFY', {
otp: this.value
}).then(success => {
console.log(success)
}).catch(error => {
console.log(error)
})
}
}
</script>
I think it's the problem with authorization part. Please help me.
isAuthenticated is funtion used to get data from localStorage
export const isAuthenticated = () => {
if (localStorage.getItem('auth')) {
return JSON.parse(localStorage.getItem('auth'))
}
return false
}
406 error is appearing because of Accept parameter in the header try after removing "Accept: 'application/json'"
I have start my first unit test in react with jest this afternoon. The 5 firsts tests that i have to do are about testing the return functions. No so difficult.
But i have difficulty to understand how to unit test my function login that return something i dont understand yet. Is someone see what i have to put in my action.test.js, show me and explain me ?
How can i unit testing login and what represent the dispatch that return the login function ?
**In action.js**
<pre>
import { userConstants } from '../shared/constants';
import { userService } from '../shared/services';
import { history } from '../shared/helpers';
function request(user) {
return { type: userConstants.LOGIN_REQUEST, user };
}
function success(user) {
return { type: userConstants.LOGIN_SUCCESS, user };
}
function failure(error) {
return { type: userConstants.LOGIN_FAILURE, error };
}
function login(username, password) {
return (dispatch) => {
dispatch(request({ username }));
userService.login(username, password).then(
(user) => {
dispatch(success(user));
history.push('/');
},
(error) => {
dispatch(failure(error));
console.error(error); // eslint-disable-line no-console
},
);
};
}
function logout() {
userService.logout();
return { type: userConstants.LOGOUT };
}
function oldLogin() {
return { type: userConstants.OLD_LOGIN };
}
export const userActions = {
login,
logout,
oldLogin,
};
</pre>
**In service.js**
<pre>
function logout() {
// remove user from local storage to log user out
if (localStorage.getItem('user')) {
localStorage.removeItem('user');
}
}
function handleResponse(response) {
return response.text().then((text) => {
const data = text && JSON.parse(text);
if (!response.ok) {
if (response.status === 401) {
// auto logout if 401 response returned from api
logout();
window.location.reload(true);
}
const error = (data && data.message) || response.statusText;
return Promise.reject(error);
}
return data;
});
}
function login(username, password) {
return fetch(
'https://mon-api',
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username,
password,
context: {
deviceToken: '1cb1b51d19665cb45dc1caf254b02af',
},
}),
},
)
.then(handleResponse)
.then((user) => {
// login successful if there's a jwt token in the response
if (user.sessionToken) {
// store user details and jwt token in local storage to
// keep user logged in between page refreshes
localStorage.setItem('user', JSON.stringify(user));
}
return user;
});
}
export const userService = {
login,
logout,
};
</pre>
dispatch is a redux action. To be able to test you need to mock it. There are utilities like redux-mock-store that facilitate this task, refer to the following article for more details.
I am trying set a value into userSessionStorage, when i am accessing it from the authenticate() function it seems to work correctly.
However, it is not working in the .then() promise.
app/controllers/show.js
import Ember from 'ember';
import { storageFor } from 'ember-local-storage';
export default Ember.Controller.extend({
session: Ember.inject.service('session'),
userSessionStorage: storageFor('user'),
authenticator: 'authenticator:custom',
actions: {
authenticate: function() {
var credentials = this.getProperties('identification', 'password');
// ok
this.set('userSessionStorage.username', credentials.identification);
this.get('session').authenticate('authenticator:custom', credentials)
.then(function(){
// error: TypeError: Cannot read property 'set' of undefined
this.set('userSessionStorage.username', credentials.identification);
})
.catch((message) => {
console.log("message: " + message);
this.controller.set('loginFailed', true);
});
}
}
});
all you need to do is changing the following line:
this.get('session').authenticate('authenticator:custom', credentials)
.then(function(){....}
to using fat arrow notation as follows:
this.get('session').authenticate('authenticator:custom', credentials)
.then(()=>{....}
so that this context within the promise context will be your controller. See following for more about ES6 arrow functions.
It's based on my own code, so you might need to adapt it. But in your authenticator, your authenticate function may look like this :
# authenticator
authenticate(credentials) {
const { identification, password } = credentials;
const data = JSON.stringify({
auth: {
email: identification,
password
}
});
const requestOptions = {
url: this.tokenEndpoint,
type: 'POST',
data,
contentType: 'application/json',
dataType: 'json'
};
return new Promise((resolve, reject) => {
ajax(requestOptions).then((response) => {
// Set your session here
}, (error) => {
run(() => {
reject(error);
});
});
});
},