I'm currently creating an auth system using Mongo as database, Node with express as backend, and Nuxt as frontend.
I've found this authentication module https://auth.nuxtjs.org/ followed the doc, and the youtube video. I'm using Local scheme for Jwt system.
My issue is the login doesn't work successfully.
I think it doesn't work because of my user route on the backend, but not sure about that.
I also read that their is a user.autoFetch but dont know how to use it.
nuxt.config.js
modules: [
// https://go.nuxtjs.dev/axios
'#nuxtjs/axios',
'#nuxtjs/auth'
],
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
baseURL: 'http://localhost:3000/'
},
auth: {
strategies: {
local: {
endpoints: {
login: { url: 'api/auth/login', method: 'post', propertyName: 'token' },
user: { url: 'api/auth/user', method: 'get', propertyName: 'data.attributes' },
logout: false
},
tokenType: ''
}
}
},
login.vue
async submit() {
try {
let response = await this.$auth.loginWith('local', { data: this.login })
console.log(response)
} catch (err) {
console.log(err)
}
// await this.$router.push('/dashboard');
},
The response send me back a 200 status, a token, and the userId (which is in my db) but the $auth still send me loggedIn at false and I can't get information like $auth.user.email.
I tried to change the auth endpoints in the nuxt.config.js
Changed tokenType: '' to tokentype: 'Bearer'
Changed the #nuxtjs/auth version to the same as the video tutorial. (4.8.4)
I added a controller for the route user :
route :
router.get('/user', userCtrl.getUser);
controller:
exports.getUser = (req, res, next) => {
User.findOne({ _id: req.params.id })
.then(thing => res.status(200).json(thing))
.catch(error => res.status(404).json({ error }));
}
Do not hesitate to ask me more details, on the configuration, other parts of the code, or anything like that.
Thank you in advance for any kind of help !
The LinkedIn API documentation for UGC Posts seems to imply you can share a post with a document by setting shareMediaCategory: "NATIVE_DOCUMENT", but there is no additional information about how to make this work. The documentation seems limited to images/videos.
This is what I have tried so far.
const registerUpload = () => {
// Doesn't seem to be documented, but the API responses on the LinkedIn site
// returns 'urn:li:digitalmediaRecipe:feedshare-document', so it seemed like a decent guess
const type = 'document'; // 'image' or 'video' works fine
return axios({
method: 'post',
url: 'https://api.linkedin.com/v2/assets?action=registerUpload',
data: {
registerUploadRequest: {
owner,
recipes: [
`urn:li:digitalmediaRecipe:feedshare-${type}`,
],
serviceRelationships: [
{
identifier: 'urn:li:userGeneratedContent',
relationshipType: 'OWNER',
},
],
...(synchronous ? {
supportedUploadMechanism: [
'SYNCHRONOUS_UPLOAD',
],
} : {}),
},
},
headers: {
Authorization: `Bearer ${tokenInfo.token}`,
'X-Restli-Protocol-Version': '2.0.0',
},
});
}
which returns the following
{
serviceErrorCode: 100,
message: 'Field Value validation failed in REQUEST_BODY: Data Processing Exception while processing fields [/registerUploadRequest/recipes/relationshipType]',
status: 403
}
This doesn't make sense to me since registerUploadRequest/recipes/relationshipType doesn't match the documented schema. Is there another way to register document assets for UGC posts?
So I have an axios request to a rapid API, my function looks like this...
//Initialize the lookup API that utalizes rapidAPI to get breach data
app.get("/lookup/:email/:function", (req, res) => {
var options = {
method: "GET",
url: "https://breachdirectory.p.rapidapi.com/",
params: { func: `${req.params.function}`, term: `${req.params.email}` },
headers: {
"x-rapidapi-host": "breachdirectory.p.rapidapi.com",
"x-rapidapi-key": `${config.RAPID_API_KEY}`,
},
};
axios
.request(options)
.then(function (response) {
res.json(response.data);
})
.catch(function (error) {
console.error(error);
});
}
});
The res.json(response.data); will show on the page a result like this:
{
"disclaimer": "This data is aggregated from BreachDirectory, HaveIBeenPwned, and Vigilante.pw.",
"info": "For full source info, request e.g. https://breachdirectory.tk/api/source?name=Animoto",
"sources": [
"123RF",
"500px",
"Adobe",
"AntiPublic",
"Apollo",
"Bitly",
"Dave",
"Disqus",
"Dropbox",
"ExploitIn",
"ShareThis",
"Straffic",
"Ticketfly",
"Tumblr",
"VerificationsIO"
]
}
I want to loop through everything in the "sources" array, and call upon the following:
https://haveibeenpwned.com/api/v3/breach/[ITEM]
So, the first one will call upon https://haveibeenpwned.com/api/v3/breach/123RF
So each result from that call will look like this:
{
"Name": "123RF",
"Title": "123RF",
"Domain": "123rf.com",
"BreachDate": "2020-03-22",
"AddedDate": "2020-11-15T00:59:50Z",
"ModifiedDate": "2020-11-15T01:07:10Z",
"PwnCount": 8661578,
"Description": "In March 2020, the stock photo site 123RF suffered a data breach which impacted over 8 million subscribers and was subsequently sold online. The breach included email, IP and physical addresses, names, phone numbers and passwords stored as MD5 hashes. The data was provided to HIBP by dehashed.com.",
"LogoPath": "https://haveibeenpwned.com/Content/Images/PwnedLogos/123RF.png",
"DataClasses": [
"Email addresses",
"IP addresses",
"Names",
"Passwords",
"Phone numbers",
"Physical addresses",
"Usernames"
],
"IsVerified": true,
"IsFabricated": false,
"IsSensitive": false,
"IsRetired": false,
"IsSpamList": false
}
I want to make my res.json send over a JSON string that will have all the sources still there, along with the "Title","Description", and "LogoPath" from the API calls that it pulled for each one of the sources. So I will have a JSON string with the sources along with the title of each source, description of each source, and LogoPath of each source.
You have two options:
Create an array of promises and run with Promise.all
app.get('/lookup/:email/:function', async (req, res) => {
var options = {
method: 'GET',
url: 'https://breachdirectory.p.rapidapi.com/',
params: { func: `${req.params.function}`, term: `${req.params.email}` },
headers: {
'x-rapidapi-host': 'breachdirectory.p.rapidapi.com',
'x-rapidapi-key': `${config.RAPID_API_KEY}`,
},
};
axios.request(options)
.then((response) => {
const requestTasks = [];
for (let item of response.data.sources) {
const itemOption = {
method: 'GET',
url: `https://haveibeenpwned.com/api/v3/breach/${item}`,
headers: {
'content-type': 'application/json; charset=utf-8'
}
};
requestTasks.push(axios.request(itemOption));
}
return Promise.all(requestTasks);
})
.then((responseList) => {
for (let response of responseList) {
console.log(response.data);
}
})
.catch((error) => {
console.error(error);
});
});
Use async/await (promise) and for await for get data from for loop
app.get('/lookup/:email/:function', async (req, res) => {
try {
var options = {
method: 'GET',
url: 'https://breachdirectory.p.rapidapi.com/',
params: { func: `${req.params.function}`, term: `${req.params.email}` },
headers: {
'x-rapidapi-host': 'breachdirectory.p.rapidapi.com',
'x-rapidapi-key': `${config.RAPID_API_KEY}`,
},
};
const response = await axios.request(options);
for await (let item of response.data.sources) {
const itemOption = {
method: 'GET',
url: `https://haveibeenpwned.com/api/v3/breach/${item}`,
headers: {
'content-type': 'application/json; charset=utf-8'
}
};
const itemResponse = await axios.request(itemOption);
console.log(itemResponse.data);
}
} catch (error) {
console.error(error);
}
});
This how I managed to make it works.
first: I didn't had any APi key (and didn't want to register to get one) So i used a dummy Api.
although the logic stay the same as i have tested the result.
second i kept all your initial url just next to the one i used.so you can easily switch back to your original url.
finally i put comment to any critical part, and i named variable in a
way that they almost describe what they do.
so you can copy past test it to understand my logic then adapt it to your use case.
here the code
// make sure to replace /lookup by /lookup/:email/:function after testing my logic
app.get('/lookup', async (req, res) => {
try {
// in this options no change just switch back to your url
var options = {
method: 'GET',
url: 'https://jsonplaceholder.typicode.com/albums',
// url: "https://breachdirectory.p.rapidapi.com/",
// params: { func: `${req.params.function}`, term: `${req.params.email}` },
// headers: {
// 'x-rapidapi-host': 'breachdirectory.p.rapidapi.com',
// 'x-rapidapi-key': `${config.RAPID_API_KEY}`,
// },
};
// here you get all your sources list (in my case it an array of object check picture 1 bellow)
const allSources = await axios.request(options)
console.log(allSources.data);
// because my dummy api response is a huge array i slice to limited number
const reduceAllsource = allSources.data.slice(0,5);
console.log(reduceAllsource);
// note here you need to replace reduceAllsource.map by allSources.data.map
// because you don't need a sliced array
const allSourcesWithDetails = reduceAllsource.map(async (_1sourceEachtime)=>{
// here you can switch back to your original url
// make sure to replace [ITEM] by ${_1sourceEachtime}
const itemOption = await axios({
method: 'GET',
url: `https://jsonplaceholder.typicode.com/albums/${_1sourceEachtime.id}/photos`,
// url:`https://haveibeenpwned.com/api/v3/breach/[ITEM]`
headers: {
'content-type': 'application/json; charset=utf-8'
}
});
// this the place you can mix the 2 result.
const mixRes1AndRes2 ={
sources:_1sourceEachtime.title,
details:itemOption.data.slice(0,1)
}
return mixRes1AndRes2;
})
// final result look like the picture 2 below
finalRes= await Promise.all(allSourcesWithDetails);
return res.status(200).json({response: finalRes});
}
catch (error) {
console.log(error);
}
});
Picture 1
Picture 2
Unfortunately this was due to another unrelated part of my code. This is an invalid question. Sorry.
I am getting an invalid json response body error on my client using fetch() to a RESTFUL api.
This is my server POST code that is called by the client using this code:
.then(conn => {
conn.query("SELECT MAX(`messagesMinute`) FROM `statistics` LIMIT 1;")
.then(rows => { // rows: [ {val: 1}, meta: ... ]
var data = {
'messagesMinuteMAX': Object.values(rows[0])[0] // ugly ass code but i dont know a better way after searching for a while
}
res.json(JSON.stringify(data));
res.end();
})
This is my client code that uses fetch
// Request the highscore of messages per minute
fetch("http://localhost:3001/postRequestMinute", { method: 'GET', headers: {} })
.then((res) => {
return res.json();
})
.then(async (json) => {
console.log(json); // <<<<---- this is the log that retrieves the following
}).catch((err) => {
console.log(err);
});
The console.log that sends out the json response returns this:
{ "messagesMinuteMAX": 1341 }
This is verified as valid with multiple online json validaters.
My biggest problem with all of this is that everything works as intended, but it spits out this error anyways which is very annoying.
Maybe its your
res.json(JSON.stringify(data));
This what happend when I did in nodejs console
> a = [{ type: 'text', text: 'Hello, world1' }]
[ { type: 'text', text: 'Hello, world1' } ]
> JSON.stringify(JSON.stringify(a))
'"[{\\"type\\":\\"text\\",\\"text\\":\\"Hello, world1\\"}]"'
when you stringify 2 times you got 2 quote outside your object
After fetch API, try to use JSON.parse(object_string)
Hope it works for you
Tip: use typeof(variable) to verify variable type
let result
fetch("http://localhost:3001/postRequestMinute", { method: 'GET', headers: {} })
.then((res) => {
console.log(JSON.parse(res))
result = JSON.parse(res)
}).catch((err) => {
console.log(err);
});
Unfortunately this was due to another unrelated part of my code. This is an invalid question. Sorry.
I'm watching a tutorial and coding exactly as the instructor. I get this error at a point in the lesson. I get this error in my browser :
The below code is not mine, credits goes to maximilian schwarzmüller (Instructor).
Front End React function Responsible for loading posts :
loadPosts = direction => {
if (direction) {
this.setState({ postsLoading: true, posts: [] });
}
let page = this.state.postPage;
if (direction === "next") {
page++;
this.setState({ postPage: page });
}
if (direction === "previous") {
page--;
this.setState({ postPage: page });
}
const graphqlQuery = {
query: `
{
posts{
posts{
_id
title
content
creator {
name
}
createdAt
}
totalPosts
}
}
`
};
fetch("http://localhost:8080/graphql", {
method: "POST",
headers: {
Authorization: "Bearer " + this.props.token,
"Content-Type": "application/json"
},
body: JSON.stringify(graphqlQuery)
})
.then(res => {
return res.json();
})
.then(resData => {
if (resData.errors) {
throw new Error("Fetching Post Failed");
}
this.setState({
posts: resData.data.posts.posts.map(post => {
return {
...post,
imagePath: post.imageUrl
};
}),
totalPosts: resData.data.posts.totalPosts,
postsLoading: false
});
})
.catch(this.catchError);
};
Server code attached : REMOVED
I'm attaching my whole code because I really don't know where the error is coming from. I basically replicated my instructor's code but it didn't work in mine like his did. The Udemy community was also unable to help.
EDIT : I found the problem, it was my mistake, I redirected with 401 in my token checking if block. I did exactly the opposite, I redirected if the user was authenticated.