Trying to hook up facebook authentication for my app. I've got the backend working correctly but my authenticator (I think this is the problem) is always returning undefined.
Copying the example from from ember-simple-auth the console log on line 23 is never called, making me think something else the issue?
import Ember from 'ember';
import Torii from 'ember-simple-auth/authenticators/torii';
const {inject: {service}} = Ember;
export default Torii.extend({
torii: service(),
ajax: service(),
authenticate() {
const ajax = this.get('ajax');
return this._super(...arguments).then((data) => {
return ajax.request('http://localhost:8080/api/login', {
type: 'POST',
dataType: 'application/json',
data: {
'grant_type': 'facebook_auth_code',
'auth_code': data.authorizationCode
}
}).then((response) => {
console.log("CALLED!");
return {
access_token: response,
provider: data.provider
};
});
});
}
});
The response from the server is the access_token from facebook;
How can I better debug/solve what's going on here?
The problem was actually a simple error with the dataType used. It should be dataType: 'json' not dataType: 'application/json'
Related
I am in a next-js app and my auth token is stored in cookies.
For some raisons i use Swr and Api route to fetch my secured api backend.
i am trying to find a way to put my auth token in all api request.
During login cookie is set
res.setHeader(
'Set-Cookie',
cookie.serialize('token', data.access_token, {
httpOnly: true,
secure: process.env.NODE_ENV !== 'development',
maxAge: data.expires_in, // 1 week
sameSite: 'strict',
path: '/',
}),
);
This is an example of a page using swr fetch
//page/test.ts - example of my test route
const { data, error } = useFetchContent(id);
if (error) {
showError('error');
replace('/');
}
return <DisplayContent content={data} />
This is a swrFetchHook
// fetchContentHook
function useFetchContent(id: string): ContentDetail {
return useSWR<any>(`/api/content/${id}`, fetcherApiRoute);
}
const fetcherApiRoute = (url: string): Promise<any> => {
return axios(url)
.then((r) => r.data)
.catch((err) => {
console.info('error is ', err)
throw err
});
};
export default useFetchContent;
inside api route
export default async (req, res): Promise<ContentDetail> => {
const { id } = req.query;
if (req.method === 'GET') {
const fetchRealApi = await apiAxios(url);
if(fetchRealApi) {
// here depending on result of fetchRealApi i add some other fetch ...
return res.status(200).json({ ...fetchRealApi, complement: comp1 });
}
return res.status(500)
}
return res.status(500).json({ message: 'Unsupported method only GET is allowed' });
};
and finally api axios configuration
const apiAxios = axios.create({
baseURL: '/myBase',
});
apiAxios.interceptors.request.use(
async (req) => {
// HERE i am trying to get token from cookies
// and also HERE if token is expired i am trying to refresh token
config.headers.Authorization = token;
req.headers['Content-type'] = 'application/x-www-form-urlencoded';
return req;
},
(error) => {
return Promise.reject(error);
},
);
export default apiAxios;
I am stuck here because i cant find token during apiAxios.interceptors.request.use...
Did you know what i am doing wrong, and am i on a correct way to handle this behavior ?
To allow sending server cookie to every subsequent request, you need to set withCredentials to true. here is the code.
const apiAxios = axios.create({
baseURL: '/myBase',
withCredentials: true,
});
Nilesh's answer is right if your API is able to authorize requests based on cookies. Also it needs the API to be in the same domain as your frontend app. If you need to send tokens to the API (the one which is in the cookie), then you will need a small backend component often called BFF or Token Handler. It can extract the token from the cookie and put in an Authorization header.
At Curity we've created a sample implementation of such a Token Handler, of which you can inspire: https://github.com/curityio/kong-bff-plugin/ You can also have a look at an overview article of the Token Handler pattern.
I'm using contact forms 7, and in my form submission I use this function:
const formData = {
'your-name':'John Doe',
'your-email': 'johndoe#mail.com',
}
axios({
method: 'POST',
url: 'https://0xsociety.com/wp-json/contact-form-7/v1/contact-forms/258/feedback',
headers: {
"content-type": "multipart/form-data",
},
data: formData,
})
But it doesnt work, i get errors saying fields are empty.
But I tried with postman and it works perfectly when i do it manually
How would I get my axios post request to mimic this:
https://gyazo.com/e1ffe5bcc3f943a074d9b9e2c32b162d
I figured this out by using postman in my app:
import request from 'postman-request'
const formData = {
'your-name': name,
'your-email': email,
'your-subject': inquiries.find(x=> x.value === inquiry).text,
'file-871': file
}
request.post('https://your-domain/wp-json/contact-form-7/v1/contact-forms/your-form-id/feedback',{ form: formData}, function(err,httpResponse,body){
if(err) {
console.log(err)
}
else {
console.log(body)
}
})
I have been using nuxt/auth-next and axios modules with nuxt project since last 3-4 months, everything was working fine since yesterday but now whenever I try to send axios request to public APIs without passing Authorization in headers, I get this error
Cannot read property 'Authorization' of undefined with Nuxt Auth & Axios
Attached is a screenshot of the page
below is my code in index.js store file
export const actions = {
async nuxtServerInit({ commit }, context) {
// Public profile
if (context.route.params && context.route.params.subdomain) {
context.$axios.onRequest((config) => {
config.progress = false
})
let { data } = await context.$axios.get(
`users/get_user_data_using_subdomain/${context.route.params.subdomain}`,
{
headers: {
'Content-Type': 'multipart/form-data',
},
}
)
await context.store.dispatch('artists/setPublicProfile', data.user_data)
}
},
}
This happend to me to when I was using context.app.$axios instead of context.$axios within a injection
Nuxt server is looking for config.headers.common.Authorization.
The example below is a quick win for you:
let { data } = await context.$axios.get(
`users/get_user_data_using_subdomain/${context.route.params.subdomain}`,
{
headers: {
common: null, // or something like this: context.$axios.defaults.headers?.common
'Content-Type': 'multipart/form-data',
},
}
)
Forgive me if it's a silly question, but the last time I coded in javascript was almost 20 years ago... I'm re-learning javascript these weeks and I'm not sure I got it all.
I'm using hapi with rest-hapi and want to add some standalone endpoints, basically translating the backend portion of this Autodesk tutorial form express.
I'm using the basic rest-hapi example main script, and tried to add a route with the following code:
//api/forge.js
module.exports = function(server, mongoose, logger) {
const Axios = require('axios')
const querystring = require('querystring')
const Boom = require('boom')
const FORGE_CLIENT_ID = process.env.FORGE_CLIENT_ID
const FORGE_CLIENT_SECRET = process.env.FORGE_CLIENT_SECRET
const AUTH_URL = 'https://developer.api.autodesk.com/authentication/v1/authenticate'
const oauthPublicHandler = async(request, h) => {
const Log = logger.bind('User Token')
try {
const response = await Axios({
method: 'POST',
url: AUTH_URL,
headers: {
'content-type': 'application/x-www-form-urlencoded',
},
data: querystring.stringify({
client_id: FORGE_CLIENT_ID,
client_secret: FORGE_CLIENT_SECRET,
grant_type: 'client_credentials',
scope: 'viewables:read'
})
})
Log.note('Forge access token retrieved: ' + response.data.access_token)
return h.response(response.data).code(200)
} catch(err) {
if (!err.isBoom){
Log.error(err)
throw Boom.badImplementation(err)
} else {
throw err
}
}
}
server.route({
method: 'GET',
path: '/api/forge/oauth/public',
options: {
handler: oauthPublicHandler,
tags: [ 'api' ],
plugins: {
'hapi-swagger': {}
}
}
})
}
The code works and I can display the access_token in nodejs console, but swagger doesn't get the response:
At first I thought that an async function cannot be used as handler, but my hapi version is 17.4.0, and it supports async handlers.
What am I doing wrong?
It turns out it was an easy fix: I just needed to specify the Hapi server hostname in my main script!
The problem was with CORS, since Hapi used my machine name instead of localhost. Using
let server = Hapi.Server({
port: 8080,
host: 'localhost'
})
solved my problem.
I am working on a mobile app which I will be deploying using Phonegap.
Now I am able to login using Drupal 7 services and I am also getting the session name and session id. But I am not able to Logout the user. When even I am doing that.. I see this issue on my chrome console: 406 (Not Acceptable:)
I tried sending headers as "Cookie" then "sessionname=sessionid" format.. but that didn't work. Can someone please suggest a way.
You need to add the CSRF token from YOUR_SITE/services/session/token, and then add it to the header in the same way you added the Cookie, something like
'X-CSRF-Token: ' + $token
And make sure it's PUT, there is a nice example here:
http://pastebin.com/N35SN7Xj
The relevant section looks like this:
$.ajax({
url: "http://your_url/endpoint/user/logout.json",
type: 'post',
dataType: 'json',
beforeSend: function (request) {
request.setRequestHeader("X-CSRF-Token", token);
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Failed to logout');
alert(JSON.stringify(jqXHR));
alert(JSON.stringify(textStatus));
alert(JSON.stringify(errorThrown));
},
success: function (data) {
alert("You have been logged out.");
}
});
This works for me.
$http({
method: 'POST',
url: drupal_instance + api_endpoint + 'user/logout',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'X-CSRF-Token': user.token
}
})
.success(function (data, status, headers, config) {
alert('Success');
})
.error(function (data, status, headers, config) {
alert('Error');
});