How to make a api call using axios to a cgi file - react-native

I'm using axios to make a call to an API that I created, I'm passing two values email and password.
My api always retrn empty because my cgi file is not getting anything for email & password from axios or
postmate(using to test the api call), but if in the browser I load the full url it works fine.
Any ideas what am I doing wrong.
Part of the form
initialValues = {{email: '', password:''}}
onSubmit = {(values, {setSubmitting}) => {
if (values.email == '' || values.password == '') {
handleMessage("Please fill all the fieldss");
setSubmitting(false);
} else {
handleMessage("");
setSubmitting(true);
handleLogin(values, setSubmitting);
}
}}
AXIOS CALL
const handleLogin = (data, setSubmitting) => {
const url = 'https://mydesitte.or/register.cgi';
axios
.post(url, data)
.then((response) => {
// const result = response.data;
// const {message, status, data} = result;
alert(data.email);
setSubmitting(false);
}).catch(error => {
alert(error);
setSubmitting(false);
});
}
CGI file
my $cgi = new CGI;
# This is always empty when I do the call from the my react native app or postmate
my $email = $cgi->param('email');
my $password = $cgi->param('password');
If I go to this url on the browser https://mysite.or/register.cgi?email=email&password=pass work fine

You need to pass POST data as an object:
axios.post(url, {
email: email,
password: pass
})

Related

How do you make a post request via Fetch in Nativescript?

I have a server.js file. With a post request (/login). It looks like this:
require('dotenv').config();
const express = require('express');
const mysql = require('mysql')
const app = express();
const PORT = process.env.PORT || 3000
app.listen(PORT, console.log(`Server started on port ${PORT}`))
app.post('/login', (req, res) => {
console.log("login")
console.log(req);
})
I also have a function in NativeScript that is supposed to make a post request (where the fetch is) when a button is pressed. It looks like this:
export function onLoginButtonTap() {
console.log("login button tapped")
const frame = Frame.getFrameById("mainFrame");
// TODO: user authentication
var userEmail = `${bindingContext.get('email')}`;
var userPassword = `${bindingContext.get('password')}`;
// make sure fields are filled out
if (userPassword === "" || userEmail === "") {
alert({
title: "Login Error",
message: "One or more fields is empty. Please fill in every field.",
okButtonText: "OK",
})
} else {
// TODO: post request (send user input to backend for verification)
console.log("here1")
const data = {userEmail, userPassword};
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}
fetch("http://localhost:3000/login", options);
// if user is in database change page to home
frame.navigate("pages/home/home-page");
}
// navigates to home page without requiring login info (for testing)
frame.navigate("pages/home/home-page");
}
The post request doesn't work. I would like the console.logs in the server file to print the request. I think the problem is how I wrote the post request? Currently nothing happens.
Fetch return a promise, you need to resolve it to actually make the POST request. Try the following block of code.
fetch('http://localhost:3000/login', options)
.then((response) => response.json())
.then((result) => {
console.log('Success:', result);
})
.catch((error) => {
console.error('Error:', error);
});

filter query param not working through axios get from my vue js application?

whenever a user types anything into the textfield, an axios get request to the url
http://sandbox4.wootz.io:8080/api/data/1/action/?filter={id}like'%TE%' is made and it is supposed to return back all the filtered results based on the search(what user has typed) as a response. But currently rather than returning the filtered results as a response it is giving out all results(non-filtered results).
NOTE: I have tested the above mentioned URL through postman by making a get request and it gave out the filtered results perfectly.Why is the same not happening through my application code?plz help
getAsyncDataAction: debounce(function(name) {
if (!name.length) {
this.dataAction = [];
return;
}
this.isFetching = true;
api
.getSearchData(this.sessionData.key,`/action/?filter={id}like'%${name}%'`)
.then(response => {
this.dataAction = [];
response.forEach(item => {
this.dataAction.push(item);
});
console.log('action results are'+JSON.stringify(this.dataAction)) //displays all the results(non-filtered)
})
.catch(error => {
this.dataAction = [];
throw error;
})
.finally(() => {
this.isFetching = false;
});
}, 500),
api.js
import axios from 'axios';
const props = {
base_url: '/api/store',
search_url: '/api/entity/search',
cors_url: 'http://localhost',
oper_url: '/api'
};
axios.defaults.headers.get['Access-Control-Allow-Origin'] = props.cors_url;
axios.defaults.headers.post['Access-Control-Allow-Origin'] = props.cors_url;
axios.defaults.headers.patch['Access-Control-Allow-Origin'] = props.cors_url;
async function getSearchData(key, path) {
try {
console.log('inside getSearchData path value is'+path)
console.log('inside getSearchData and url for axios get is '+props.base_url + '/data' + path)
let response = await axios({
method: 'get',
url: props.base_url + '/data' + path,
headers: {'session_id': key}
});
if (response.status == 200) {
console.log(response.status);
}
return response.data;
} catch (err) {
console.error(err);
}
}
The problem is that you're not encoding the query string correctly. In particular, your % signs need to become %25
To do this, I highly recommend using the params options in Axios.
For example
async function getSearchData(key, path, params) { // 👈 added "params"
// snip
let response = await axios({
method: 'get',
url: `${props.base_url}/data${path}`,
params, // 👈 use "params" here
headers: {'session_id': key}
});
and call your function with
const params = {}
// check for empty or blank "name"
if (name.trim().length > 0) {
params.filter = `{id}like'%${name}%'`
}
api
.getSearchData(this.sessionData.key, '/action/', params)
Alternatively, encode the query parameter manually
const filter = encodeURIComponent(`{id}like'%${name}%'`)
const path = `/action/?filter=${filter}`
Which should produce something like
/action/?filter=%7Bid%7Dlike'%25TE%25'

Trying to set a cookie established on a web session as a header back to API

I am trying to login via the webfront end and trying to intercept a cookie and then using that in the subsequent API request. I am having trouble getting the cookie back into the GET request. Code posted below.
import https from 'https';
import { bitbucketUser } from "../userRole.js"
import { ClientFunction } from 'testcafe';
fixture `Request/Response API`
// .page `https://myurl.company.com/login`
.beforeEach(async t => {
await t.useRole(bitbucketUser)
});
test('test', async t => {
const getCookie = ClientFunction(() => {
return document.cookie;
});
var mycookie = await getCookie()
const setCookie = ClientFunction(mycookie => {
document.cookie = mycookie;
});
var validatecookie = await getCookie()
console.log(validatecookie)
const executeRequest = () => {
return new Promise(resolve => {
const options = {
hostname: 'myurl.company.com',
path: '/v1/api/policy',
method: 'GET',
headers: {
'accept': 'application/json;charset=UTF-8',
'content-type': 'application/json'
}
};
const req = https.request(options, res => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
let body = "";
res.on("data", data => {
body += data;
});
res.on("end", () => {
body = JSON.parse(body);
console.log(body);
});
resolve();
});
req.on('error', e => {
console.error(e);
});
req.end();
});
};
await setCookie(mycookie)
await executeRequest();
});
I have tried several examples but am quite not able to figure what is it that I am missing.
When you call the setCookie method, you modify cookies in your browser using the ClientFunction.
However, when you call your executeRequest method, you run it on the server side using the nodejs library. When you set cookies on the client, this will not affect your request sent from the server side. You need to add cookie information directly to your options object as described in the following thread: How do I create a HTTP Client Request with a cookie?.
In TestCafe v1.20.0 and later, you can send HTTP requests in your tests using the t.request method. You can also use the withCredentials option to attach all cookies to a request.
Please also note that TestCafe also offers a cookie management API to set/get/delete cookies including HTTPOnly.

React-native axios with ColdFusion component

I'm trying to send a get request from react native, using axios, to my coldfusion component.
My coldfusion component:
component displayName="react" {
remote any function ajaxLogin(data) returnformat="JSON"{
data = deserializeJSON(arguments.data);
return serializeJSON(login(data));
}
private any function login(data){
loginQuery = new query();
loginQuery.setDatasource("ds");
loginQuery.setName("loginQuery");
loginQuery.addParam(name="UserEmail", value="#arguments.data.userEmail#", cfsqltype="cf_sql_varchar");
loginQuery.addParam(name="UserPW", value="#arguments.data.userPassword#", cfsqltype="cf_sql_varchar");
result = loginQuery.execute(sql="SELECT * FROM Users Where UserEmail = :UserEmail AND UserPW = :UserPW");
rs = result.getResult();
if(rs.recordCount == 0){
return 0;
} else {
return rs.UserID;
}
}
}
My react-native dispatch action:
export const loginUser = ({ email, password }) => {
// login
return (dispatch) => {
dispatch({ type: 'TEST' });
axios.get('https://myserver.com/components/reactNative/react.cfc?method=ajaxLogin', {
params: {
userEmail: email,
userPassword: password
}
})
.then((response) => {
console.log(response.data);
})
.catch((err) => {
console.log(err);
});
};
};
It is returning an error from the catch:
Error: Request failed with status code 500
I am new with axios and react-native. Am I using axios wrong?
Thanks
Status code 500 is a server-side error so you're likely getting a Coldfusion error, check your ColdFusion logs.
Also as you're calling this as a GETrequest you can just open the URL in a browser tab and see if you get any errors dumped to the page (in a development environment)
https://myserver.com/components/reactNative/react.cfc?method=ajaxLogin&userEmail=email&userPassword=password
If this is production then you should see errors in your error logs (somewhere like /var/www/opt/coldfusion_11/cfusion/logs on linux)

next js redux-observable persistent auth token using cookie

I have been trying to implement react server-side-rendering using next, and redux-observable, now i want to implement auth
On signin
click signin
dispatch signin
set signin type
set signin data
call backend api auth/signin
if the response says that token is expired
call backed api auth/refresh using refreshToken
set cookie based on auth/refresh response token
set auth data based on auth/refresh response
else
set cookie based on auth/signin response token
set auth data based on auth/signin response
On accessing pages that needs auth
check for cookies called token
if exists
call backed api auth/me to authorize
if the response says that token is expired
call backed api auth/refresh using refreshToken
set cookie based on auth/refresh response token
set auth data based on auth/refresh
else
set auth data based on auth/me response
else
redirect to signin
Steps above happens inside the epics, as follows
/epics/signin.js
export const signinEpic = (action$, store) => action$
.ofType(SIGNIN)
.mergeMap(() => {
const params = { ... }
return ajax(params)
.concatMap((response) => {
const { name, refreshToken } = response.body
if (refreshToken && name === 'TokenExpiredError') {
const refreshParams = { ... }
return ajax(refreshParams)
.concatMap((refreshResponse) => {
setToken(refreshResponse.body.auth.token)
const me = { ... }
return [
authSetMe(me),
signinSuccess(),
]
})
.catch(error => of(signinFailure(error)))
}
const me = { ... }
setToken(response.body.auth.token)
return [
authSetMe(me),
signinSuccess(),
]
})
.catch(error => of(signinFailure(error)))
})
I did some console.log(Cookies.get('token')) to ensure that the cookie gets saved, and it prints the token just fine, saying that its there, but when i checked under browser console > Application > Cookies, nothing is there
So in auth epic below, the getToken() will always return '' which will always dispatch authMeFailure(error)
/epics/auth.js
// this epic will run on pages that requires auth by dispatching `authMe()`
export const authMeEpic = action$ => action$
.ofType(AUTH_ME)
.mergeMap(() => {
const params = {
...,
data: {
...
Authorization: getToken() ? getToken() : '', // this will always return ''
},
}
return ajax(params)
.mergeMap((response) => {
const { name, refreshToken } = response.body
if (refreshToken && name === 'TokenExpiredError') {
const refreshParams = { ... }
return ajax(refreshParams)
.mergeMap((refreshResponse) => {
setToken(refreshResponse.body.auth.token)
const me = { ... }
return authMeSuccess(me)
})
.catch(error => of(authMeFailure(error)))
}
const me = { ... }
setToken(response.body.auth.token)
return authMeSuccess(me)
})
.catch(error => of(authMeFailure(error)))
})
I use js-cookie for getting and setting cookies
EDIT: i actually prepared an auth lib containing getToken, setToken and removeToken, as follows
import Cookies from 'js-cookie'
export const isAuthenticated = () => {
const token = Cookies.get('token')
return !!token
}
export const getToken = () => Cookies.get('token')
export const setToken = token => Cookies.set('token', token)
export const removeToken = () => Cookies.remove('token')
and yes, i could have just used the setToken() on the epics, was just trying to directly test the cookie set method
UPDATE:
it seems that despite its not being in Console > Application > Cookies, its exists on every pages as it's printing the correct token if i do console.log(getToken()) inside the component render method
But every time i refresh the page, its gone. Kind of like it is being stored in a redux state, which is weird
UPDATE #2:
ok i think i manage to make it work, it turns out that we need 2 types of cookie, server side (the one's generated on refresh) and a client side (persist on navigating), so the reason that i wasn't able to get the token on epics its because it was not passed from the server side (at least this is my understanding)
Inspired by this issue comment on github
yarn add cookie-parser
on ./server.js (you need to have a custom server to be able to do this)
const cookieParser = require('cookie-parser')
...
server.use(cookieParser())
on ./pages/_document.js
export default class extends Document {
static async getInitialProps(...args) {
// ...args in your case would probably be req
const token = args[0].req ? getServerToken(args[0].req) : getToken()
return {
...
token,
}
}
render() {
...
}
}
on ./lib/auth.js or on any place you put your token methods
export const getServerToken = (req) => {
const { token = '' } = req.cookies
return token
}
export const getToken = () => {
return Cookies.get('token') ? Cookies.get('token') : ''
}
I am not 100% understand how this is solving my problem, but i am gonna leave it like this for now