Reactjs Axios / Spring boot security - reactjs

I have a Java application developed with Spring Boot which is the back-end.
The front-end is an application developed in ReactJs. I use REST services.
I use axios for REST calls.
I recently enabled the security in Spring Boot. Now I have difficulty to authenticate axios calls.
var config = {
auth: {
username: 'bruker',
password: 'passord'
}
};
axios.get('http://localhost:8090/employee/all', config).then(function (response) {
console.log(response)
}.bind(this)).catch(function (response) {
console.log(response)
}.bind(this))
I get the following error "Response for preflight is invalid (redirect)"
I assume the response is a redirected to localhost:8090/login
I haven't found any solutions to this. What do I do wrong?

This post is old now, but I ran into a similar problem here in good 'ole 2018. Using Axios as follows got things working for me:
axios('/user', {
method: 'POST',
auth: {
username: myUser,
password: myPassword
}
}).then((response => {
...
})).catch((error) => {
...
})
Notice that the difference is replacing axios.get(... with axios(....
Remove the method type as a function and include it as a config option. It could have something to do with the way axios is imported (import axios from 'axios'), but I didn't delve into that once I got my stuff working.
Hope that helps!

Related

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);
});

Understanding Next.JS with-iron-sessions requirements for use in own environment

I am trying to get some of the examples located in the with-ireon-sessions github account to work with my own back-end: https://github.com/vercel/next.js/tree/canary/examples/with-iron-session
I can sign in using const { user, mutateUser } = useUser(); with useUser() being from the example: https://github.com/vercel/next.js/blob/canary/examples/with-iron-session/lib/useUser.js
My sign-in method looks like this;
const signIn = async ({ email, password, remember_me }) => {
try {
await mutateUser(
fetchJson(`${API.baseURL}/${API.signIn}`, {
method: "POST",
headers: {
"Accept": 'application/json',
"Content-Type": "application/json"
},
body: JSON.stringify({
email,
password
})
})
);
} catch (error) {
console.error("An unexpected error happened:", error);
setErrorMessage((<p className="error">{error.data.message}</p>));
}
};
I can see my user change, but I still have the following issues:
I don't see any cookies get created. Does with-iron-sessions require the site to be deployed to the vercel cloud in order for cookies to get added, or am I right in thinking I can use my own server and API endpoints?
What's the pattern for using the /api/user endpoint in useUser.js; does the endpoint look for the cookies (that are not getting created for me) and do it's own validation, or is there validation I need to do in my version of that endpoint? Is there an example of what that endpoint looks like server-side you might be able to point me to?
Is there a way to refresh the cookie (once I get them to appear) so they are X days since last using the site instead of X days from first login so it's a sliding cookie lifespan, or does that happen automatically?
When I sign out my sign_out endpoint returns a 204 status code but the UI doesn't change like it does when I sign in. Any tips for me there?
Thank you!

POST Request to Azure DevOps Rest API with Reactjs

So far I've been able to configure a method in C# that is able to hardcode a new repository in Azure DevOps, but my real goal is to create a user interface that allows the user to specify the request body which consists of the following:
name: 'nameOfRepository',
project: {
id: 'projectId'
}
The user will fill out the first input field with the desired name of the new repository. The second input field should use a GET Request that displays all available projects in your organization in a dropdown list.
I'm also using .NET Core 3.0 and believe this probably has to be done with an API controller as well, but I am not certain.
I have little to no experience with React and have no idea how and where I'm going to specify the request body and personal access token to create the repository. I would appreciate an explanation of how this works and would also appreciate a solution that could guide me in the right direction.
Azure DevOps Rest API Documentation will give you access to the platform. If you are decided to develop totally in React js. I would like to suggest to take a starter kit, mostly will cover all your basic setup to React.
Follow the below steps to get an idea of how you can achieve with react js
Need to set up OAuth in azure deops. The below link will give an idea. In the callback page, you need to store access token store
https://learn.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/oauth?view=azure-devops. If you have personal auth token this is not required
Get all list of repositories using fetch or Axios API
Example with Axios:
const headers = {
'Content-Type': 'application/json',
'Authorization': 'bearer token' or 'basic personalaccesstoken'
}
axios.get('https://dev.azure.com/{organization}/{project}/_apis/git/repositories', {
headers: headers,
params: {
'api-version':'5.1'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Use react form to capture the input value and on submit of form, validate against the repositories, if it is new call the Axios or fetch post method to create a new repository
Example with Axios
const headers = {
'Content-Type': 'application/json',
'Authorization': 'bearer token'
}
const data = {
name: ''
parentRepository: {id: '', ....}
project: {id: '', ...}
}
axios.post('https://dev.azure.com/{organization}/{project}/_apis/git/repositories', JSON.stringify(data),
{
headers: headers,
params: {
'api-version':'5.1'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Similarly, you can access all the API's mentioned REST API documentation of Microsoft. link

How to do Basic Authentication from React Axios GET call to a SpringBoot microservice

Postman Request Details
I am using axios.get() to call a secured SpringBoot Microservice but it returns a 401 Unauthorized response.
Postman returns the output as expected for SpringBoot Microservice but not the React App
I have tried all the possibilities available on internet but in vain.
Please help me get a solution to this.
React Call: passing auth as parameter as it is the way to do Basic Authentication in Axios
axios.get('http://localhost:8080/hellouser/greet/',
{},
{auth:{
username:'demouser',
password:'demopassword'
}}).then(function (response) {
console.log(response);
})
Try this approach instead
axios.get('http://localhost:8080/hellouser/greet/', {
params: {},
withCredentials: true,
auth: {
username: 'myusername',
password: 'mypassword'
}
})
You might also check the version of the library. It may vary from one to another

reactjs make https (not http) requests with axios

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)
});

Resources