reactjs make https (not http) requests with axios - reactjs

I'm trying to make https requests to the server using axios. Most of the tutorials regarding axios specify how to make http requests.
I make the requests whenever users login. Here is my current request:
axios.post('/api/login/authentication', {
email: email,
password: password
})
.then(response => {
this.props.history.push('/MainPage')
})
.catch(error => {
console.log(error)
})
Can anyone help me convert this to an https request?

All URLs have two parts
Domain - http://yourdomain.com
Path - /path-to-your-endpoint
1. Use default domain
In axios, if you specify just the path, it will use the domain in the address bar by default.
For example, the code below will make a call to whatever domain is in your address bar and append this path to it. If the domain is http, your api request will be a http call and if the domain is https, the api request will be a https call. Usually localhost is http and you will be making http calls in localhost.
axios.post('/api/login/authentication', {
2. Specify full URL with domain
On the other hand, you can pass full URL to axios request and you will be making https calls by default.
axios.post('https://yourdomain.com/api/login/authentication', {
2. Use axios baseURL option
You can also set baseURL in axios
axios({
method: 'post',
baseURL: 'https://yourdomain.com/api/',
url: '/login/authentication',
data: {
email: email,
password: password
}
}).then(response => {
this.props.history.push('/MainPage')
})
.catch(error => {
console.log(error)
});

Related

Client does not receive cookies from server, postman does

There is a server, which serves my client react app at root path. So when I make any request to server from POSTMAN, to login for example, cookies are attached perfect. But when I make request from my client using AXIOS and withCredentials field as well, cookies ain't attached, nevertheless the request is sent good, but no cookies received. I don't think there is any reason to search issues in server code, because postman works with it perfect. In case, there is no CORS errors: server provides client app. I get nice response from the server, with no cookies. Postman gets them.
axios request in react app:
export const login = createAsyncThunk(
'auth/login',
async (credentials: ILogin) => {
// todo: making a request to server
const response = await axios({
url: '/api' + '/auth' + '/login',
method: 'POST',
data: credentials,
withCredentials: true,
headers: {
'Content-Type': 'application/json'
},
});
console.log(response)
}
)
Client doesn't receive cookies, neither on localhost nor deployed app.
As you see, only place where cookies are shown it's network section in devtools, but everything else, including server acts like my second request hadn't any cookie, because in this case, server would answer like: agh, already logged in
P.S: i'm using http

How to fetch data from a REST API by using an API-Token

I'm trying to fetch data from the Jira Rest API in my React application by using the Axios library for http requests. An API token is necessary, in order to access data via the Jira API. I generated an API token in my Jira account settings, but I can't figure out, how to include it in my http request to gain access.
This is the endpoint provided by the Jira documentation for getting an issue from the Jira board:
curl -u admin:admin http://localhost:8080/jira/rest/api/2/issue/TEST-10 | python -mjson.tool
This is the React state hook for setting the data to the fetched data:
const [jiraTicket, setJiraTicket] = useState([]);
This is the fetch function for the API request (${} will be filled with user input):
function getJiraTicket() {
axios.get(`${username}:${apiToken}#Content-Type:application/json/https:/${jiraSiteName}.atlassian.net/rest/api/2/issue/${projectKey}-${ticketId}`)
.then((res) => {
const data = res.data;
setJiraTicket(data);
})
}
The button inside the react component return should invoke the fetch function:
return(
<Container>
<Button onClick{getJiraTicket()}>Fetch Jira Ticket</Button>
</Container>
);
This is the error I'm currently getting, because the authorization is not working the way I did it
(I replaced the provided username, API token etc. for this example):
GET http://localhost:3000/username:apitoken#https:/sitename.atlassian.net/rest/api/2/issue/projectkey-ticketid 404 (not found)
Edit:
My current approach:
function getJiraTicket() {
axios.get(`${userName}:${apiToken}#https://${siteName}.atlassian.net/rest/api/2/issue/${projectId}-${ticketId}`,{
auth: {
username: userName,
password: apiToken,
},
withCredentials: true
})
.then((res) => {
const data = res.data;
console.log(data);
setJiraTicket(data);
})
.catch(err => {
// This error means: The request was made and the server responded with a status code
if(err.res) {
console.log(err.res.data);
console.log(err.res.status);
console.log(err.res.headers);
console.log("request was made and server responded with status");
// The request was made but no response was received
} else if (err.request) {
console.log(err.request);
console.log("request was made, but no response was received");
// Something happened in setting up the request that triggered an error
} else {
console.log("Error", err.message);
console.log("request is note set up correctly");
}
console.log(err.config);
})
Current error, which I defined accordingly to the axios doc: "request was made, but no response was received"
Endpoint that works well in Postman (Basic auth is provided in Postman):
https://sitename.atlassian.net/rest/api/2/issue/projectid-ticketid
Update: CORS access isn't allowed, when an application tries to access the Jira API endpoints directly. This restriction takes place in order to prevent random authenticated requests to the specific Jira site, because the access is based on session based authentication. However the API endpoints can be accessed, if OAuth 2.0 is used instead of Basic auth, because the application will redirect the user to the Jira auth itself via this link:
https://auth.atlassian.com/authorize? audience=api.atlassian.com&
client_id=YOUR_CLIENT_ID&
scope=REQUESTED_SCOPE_ONE%20REQUESTED_SCOPE_TWO&
redirect_uri=https://YOUR_APP_CALLBACK_URL&
state=YOUR_USER_BOUND_VALUE& response_type=code& prompt=consent
Source: https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/#known-issues
Axios uses a headers config for get/post so you should not include them in your URL. Here is a general example of how you should construct the URL and apply headers:
let axiosUrl = `https://${jiraSiteName}.atlassian.net/rest/api/2/issue/${projectKey}-${ticketId}`
axios({
baseURL: axiosUrl,
method: 'get',
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin", "*"
},
//timeout: 2000,
auth: {
username: userName,
password: apiToken,
}
})
.then((res) => {
setJiraTicket(res.data);
})
.catch(function (error) {
console.log(error);
});

React and Axios get AWS client credentials

I'm using latest version of react with axios and want to get an authentication token from aws / cognito. Therefore I have my client and client secret. When I send a curl request, it works as expected, but when I send the request via axios, I always get a status 405 response.
My code looks as follows:
...
axios({
url: 'https://xyz.amazoncognito.com/oauth2/token?grant_type=client_credentials',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'client_id': '***************',
'client_secret': '****************'
'redirect_uri': 'http://localhost:4200'
}
})
.then((response) => {
console.log(response);
}, (error) => {
console.log(error);
});
Instead of setting client_id, client_secret and redirect_uri to the headers, I added them in the url like
...grant_type=client_credentials&client_id=************&client_secret=*************&redirect_uri=http%3A%2F%2Flocalhost%3A4200
with the same result. Any ideas, what I'm doing wrong? As a side remark: I'm using axios for all my api requests and so I would like to stay at axios also in this case.
Thanks and kind regards,
Balu
You are not passing the required parameters correctly. Have a look at the example here:
https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html
The required headers will be:
Authorization
If the client was issued a secret, the client must pass its client_id and client_secret in the authorization header through Basic HTTP authorization. The secret is Basic Base64Encode(client_id:client_secret).
Content-Type
Must always be 'application/x-www-form-urlencoded'.
The other information will be passed as request parameters.
This being said, you should not store your client and client secret on the client side (React application). If this is exposed on the client, anyone can get your client ID and Client secret and obtain a Cognito Token.

How can we send OAuth2.0 with axios in React js

I am working on one authentication problem where i have to implement OAuth2.0 authentication for my React App. Is there any way that i can use that authentication with Axios Promise based library???
You will have to pass your Token in the header.
See below;
const instance = axios.create({
baseURL: 'http://localhost/api/',
headers: {'Authorization': 'basic '+ token}
});
instance.get('/path')
.then(response => {
return response.data;
})
OR
Set an Authorization cookie in the browser once you get your token.
The browser will always send the Authorization cookie in each request made to the server. You won't have to pass it through Axios get/post.
UPDATE:
In order to get the access token from the oAuth server, pass the client_id, client_secret, scope and grant_type as follows;
var axios = require("axios");
axios.request({
url: "/oauth/token",
method: "post",
baseURL: "http://sample.oauth.server.com/",
auth: {
username: "myUsername", // This is the client_id
password: "myPassword" // This is the client_secret
},
data: {
"grant_type": "client_credentials",
"scope": "public"
}
}).then(respose => {
console.log(respose);
});
I am assuming that you are using grant_type = "client_credentials", if not, then based on the grant_type you use, you will have to also change the request parameters accordingly.

fetch always pass with OPTIONS method

I made API server with flask-restplus.
Also use cors module for avoid CSP issue.
And frontend is React.js.
My code is here.
class ArticleList(Resource):
def post(self):
print(1)
return {"status":"true", "result":"article write success"}, 200
React.js code is here.
_writeArticle = () => {
const { title, body, tags, password } = this.state;
const data = {title: title, body: body, tags: tags, password: password};
fetch("http://127.0.0.1:5000/article/", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: data
})
.then(res => {
if(res.status === 200) {
return <Redirect to='/' />
} else {
alert("error");
}
})
.catch(err => console.log(err))
}
I defined method to POST. But, it request with OPTIONS method.
After searched in google, that issue cause by CORS.
So I defined cors to main code like this.
from flask import Flask
from flask_restplus import Api, Resource
from api.board import ArticleList, Article
from flask_restplus import cors
app = Flask(__name__)
api = Api(app)
api.decorators=[cors.crossdomain(origin='*')]
api.add_resource(ArticleList, '/article')
api.add_resource(Article, '/article/<int:article_no>')
if __name__ == '__main__':
app.run(debug=True)
But it still request with OPTIONS.
How can I solve this issue?
That OPTIONS request is called pre-flight request.
Under some circumstances relating to CORS the web browser will first send a pre-flight request to server to check if your domain is allowed to make requests to the server or not. If the server says yes then your actual POST request will be sent. Otherwise, no additional requests will be sent and the web browser will spit an error at you.
Here is documentation on pre-flight request:
https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.1#preflight-requests
And according to the documentation:
The pre-flight request uses the HTTP OPTIONS method.

Resources