React native fetching data from secured API's endpoint with JWT - react-native

I'm developing React Native application which is connected to Web API written in ASP.NET Core 2.1. I'm trying to make GET request to my secured API's endpoint, but it doesn't work both with fetch and axios.
Noteworthy is fact, when I make request to unsecured (marked as AllowAnonymous) endpoint, everything works fine.
I'm passing following header 'Authorization' : 'Bearer ' + MY_TOKEN
When I tried to use axios, then it returned HTTP 401. When using fetch it returns HTTP 500.
const url = `${baseUrl}/api/cars/get`
fetch(url, {
headers: new Headers({
Authorization: "Bearer <MY_TOKEN_HERE>"
}), method: "GET"
})
I'm sure the token is valid because I am able to get data from API with Postman and with .NET Core console application client.
Is there any way to get the data from secured API's endpoint?

I solved the issue with just one line of code.
axios.defaults.headers.common['Authorization'] = `Bearer ${TOKEN}`
Then I am able to invoke the get request.
const url = `${baseUrl}/api/values`;
axios.get(url)
.then(data => {
console.log(data);
})
.catch(error => {
})
Hope it helps someone who will have such issue in the future.

Related

how to make a request to coinbase exchange api from localhost?

when I run the following code from the client side in javascript as the coinbase cloud documentation says https://docs.cloud.coinbase.com/exchange/reference/exchangerestapi_getcoinbaseaccounts
const options = {
method: 'GET',
headers: {
Accept: 'application/json',
'cb-access-key': 'Apikey',
'cb-access-passphrase': 'Mypassphrase',
'cb-access-sign': cb_access_sign,
'cb-access-timestamp': cb_access_timestamp
}
};
fetch('https://api.exchange.coinbase.com/coinbase-accounts', options)
.then(response => response.json())
.then(response => console.log(response))
.catch(err => console.error(err));
when I do it with axios the same thing happens
the following error appears in console: "Access to fetch at 'https://api.exchange.coinbase.com/coinbase-accounts' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field cb-access-passphrase is not allowed by Access-Control-Allow-Headers in preflight response."
what am I doing wrong?
You can't do this in the browser, you need to do it from the web server. You can either display the data when the page loads or use vue/react and write your own interaction with the webserver.
edit: doing this in the browser makes your keys visible...
Coinbase API has misconfigured CORS (or intentionally require you to make API calls from a server). Regardless, this makes it very hard to test in a dev environment. This can be solved using a proxy. This can be configured using cors-anywhere which changes the api call flow from:
Client (localhost:3000) <-> Coinbase API (api.exchange.coinbase.com)
to
Client (localhost:3000) <-> Proxy Server (www.your-proxy-server.com) <-> Coinbase API (api.exchange.coinbase.com)
In summary, coinbase will only see a request coming from your proxy server and does not care/know where the proxy server sends back the data. Cors-anywhere will also include the headers and data along with the request.
Do not use public cor-anywhere servers unless you are quickly testing something. It is best to set up your own.
Using Firebase
I used cors-server to set mine up using firebase functions. You want your Firebase functions to look like the following:
const {onRequest} = require("firebase-functions/v2/https");
const corsAnywhere = require('cors-anywhere');
const cors = require("cors")({origin:true})
const corsServer = corsAnywhere.createServer({
originWhitelist: [
'http://localhost:3000',
],
requireHeader: ['origin', 'x-requested-with'],
removeHeaders: ['cookie', 'cookie2'],
});
exports.proxy = onRequest((request, response) => {
cors(request,response,() =>{
corsServer.emit('request', request, response);
})
});
and an example of a request in your client code
return(
axios({
url: `https://proxy-your-function-id.a.run.app/https://api.exchange.coinbase.com/profiles`,
headers: await getHeaders(options),
method: 'GET',
data: options.body
}).then((response)=>{
return(response)
}).catch((err)=>{
return(err.response)
})
)
Edit: It should also be noted that Coinbase is getting rid of Coinbase Pro and its API end of 2022. Coinbase exchange and its API will still be available at https://api.exchange.coinbase.com however Pro users will be merged into Advanced Trading on their main platform which uses oAuth to link the API (or standard keys for personal projects).

get CORS problem when ty to get a token in keycloak with vuejs and axios

I trying to access one keycloak with axios in my vuejs app, but I receive the cors error, can someone help me please? (If I make a post from POSTMAN to my keycloak works fine)
I using this code:
const params = new URLSearchParams();
params.append("grant_type", "password");
params.append("client_id", "notas-front");
params.append("username", usuario.value);
params.append("password", password.value);
console.log(params);
const config = {
// withCredentials: true,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
};
axios.defaults.headers.common["Access-Control-Allow-Origin"] =
"http://localhost:8080";
axios
.post(
"http://localhost:8082/auth/realms/lumera/protocol/openid-connect/token",
params,
config
)
.then((response) => {
console.log(response);
});
and get this error:
but when I look the request I can't find the error:
the OPTIONS returns 200
but the POST dont
Postman doesn't care about Same Origin Policy, browser do. That's why your request is working in Postman but not in the browser.
Access-Control-Allow-Origin is a response header, you can't set it on the client request. And as you can see from the OPTIONS response headers your server is returning: Access-Control-Allow-Origin: http://localhost:8080
In a development environment the best way to solve this is setting a proxy in your vue configuration. Otherwise you should configure the server to allow requests from localhost:8080
Configure Web Origins properly in the Keycloak notas-front client config.

React Native - Axios - Google Identity Refresh Token 401 error

I'm using custom tokens and firebase auth. I'm successfully logging in users with email & password and storing the accessToken and refresh tokens. When I go to use the refresh token to get a new access token I'm getting a 401 error. When I try the same post link I'm using in a chrome extension based plugin (for testing REST API's) - the request is successful and I get the desired response. Though with my code in expo & react native I get just a plain, unhelpful 401 error.
My code is as follows:
const headers = {
'Authorization': `Bearer ${accessToken}`
}
const data ={
grant_type : "refresh_token",
refresh_token : refreshToken
}
await axios.post(urlTest, data, {
headers: headers
})
.then((response) => {
console.log("Success! ", response)
})
.catch((error : Error) => {
console.error(error.name, error.message);
})
Not sure what I'm doing wrong here. Maybe a cors issue? A fresh pair of eyes would be welcome.
Thanks!
Seems it might have been a CORS issue. Changed where I was hosting the code to handle posting and getting new access token. Works a treat now.

Couchdb Vue.js authentication

I'm trying to move a node/express authentication application over to vue.js. I am able to successfully authenticate getting a 200 code. However, the response returned from couchdb does not contain the "set-cookie" header, which contains the much needed AuthSession token. The code that I am using in my Vue component is:
var reqBody = "name="+user+"&password="+pass;
var reqBodyLength = reqBody.length;
console.log(reqBodyLength);
this.$http.post('http://localhost:5984/_session/', reqBody, {headers: {'Content-Type' : 'application/x-www-form-urlencoded', 'Accept' : 'application/json'}}).then(response => {
console.log("response: " + JSON.stringify(response));
console.log("response.headers: " + JSON.stringify(response.headers));
console.log("response.headers.set-cookie: " + JSON.stringify(response.headers["set-cookie"]));
}, response => {
alert('you unauthorized, fool!')
})
Has anyone ever had an issue getting the "set-cookie" header?
Thanks, Tyler
Couch's AuthSession is HttpOnly cookie and therefore can't be accessed through a client side script. But the cookie itself should be set to a browser by that _session query, so all the consequent requests will be authorized.
BTW, /_session also accepts JSON payload, at least in CouchDB 1.6, so the query doesn't have to be in x-www-form-urlencoded form.

react-native - Bearer Token auth - httpReqest

I'm new to react native and I need some help.
I'm writing an app for android with react native.
I had already implemented the login Screen and all screens that should be shown when the loggin process completed successfully.
I don't know to to make a http request with bearer auth to my localhost website.The Request Method is GET. In my app i have to enter username and password and send it to the https:/localhost/.../login.
This is working so far: I get the tipped user and password from the TextInput of the loginscreen and send both to my function called httpRequest.
function httpRequest(name, password) {
var httpResponse = null;
// not implemented yet
}
I don't know know how to start ... should i start with a fetch-Get mehtod that i can find on react-native docs ? But how should i do it with bearer token (auth)
This is a common issue newcomers face when dealing with authentication.
I recommend you to give this a good read https://auth0.com/blog/adding-authentication-to-react-native-using-jwt/
You need a bit of advanced knowledge to implement it but you will learn with it, anyways.
You'll have to send your username and password to your backend with a POST request NOT a GET. So you can attach the name and password data to the body of the request. Also you'll want to use fetch to make the request.
You can do it like this:
function httpRequest(name, password) {
const user = {
name,
password,
};
fetch('https://mywebsite.com/endpoint/', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(user)
})
.then(res => res.json())
.then(data => {
console.log(data);
// data should contain a JWT token from your backend
// which you can save in localStorage or a cookie
})
.catch(err => console.log(err));
}
Also check out my answer on this question about a fetch helper function for easily generating headers. It includes a piece in there for easily adding a JWT token to your requests.
How to post a json array in react native