How to I get token? - javascript

I am trying to implement token based authentication. The code below works on tutorial I'm watching but when I run it, I can't don't get any token. Here is the code :
axios.defaults.baseURL = "http://localhost:3002";
const [userLogin, setUserLogin] = useState({
username: "",
password: "",
});
const { username, password } = userLogin;
const handleSubmit = async (e) => {
e.preventDefault();
const data = userLogin;
const response = await axios.post("/login", data, {
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
credentials : 'include'
});
};
Preview on Network :
Any help will be appreciated. Thanks.

I don't understand the question clearly but I think that you need to do this.
yourwebscript (request) > backend server running for example nodejs js > the backend server returns a token (you send username and password).
Now you have the token and you can make the request with token.
I think I have understand it, you need to read de response with e.responseJSON in the success or completed section.

Related

Adding CSRF tokens to HTTP headers in react/spring boot project

I've been working on a React/Spring project with the ambition of better understanding spring security and while going fairly successful thus far I've found a shortage of information relating to the handling of CSRF tokens between React and Spring boot. As such, I'm at an impasse.
My question is: How do you add and authenticate a CSRF token between React and Spring Boot on POST requests?
So far I've managed to get the CSRF token into my Cookies (thanks spring) and from there, I've attempted accessing the CSRF token and adding it to my HTTP headers although still receiving 403 responses on POST requests.
My spring security config class contains the declaration enabling CSRF outside of http(withHttpOnlyFalse() ).
How I'm trying to access the CSRF token:
I found this online previously for accessing the cookie:
function getCookie(name) {
if (!document.cookie) {
return null;
}
const xsrfCookies = document.cookie.split(';')
.map(c => c.trim())
.filter(c => c.startsWith(name + '='));
if (xsrfCookies.length === 0) {
return null;
}
return decodeURIComponent(xsrfCookies[0].split('=')[1]);
}
How I'm declaring HTTP headers:
let csrfToken = getCookie("XSRF-TOKEN");
console.log("testing csrf token: " + csrfToken);
const res = await fetch(`/register`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": csrfToken,
},
body: JSON.stringify({
firstName: firstName,
lastName: lastName,
mobileNumber: mobileNumber,
email: email,
password: password,
}),
});
Any help/support is greatly appreciated.
I've managed to resolve this.
Considering the difficulty I had sourcing information here's my solution:
Install the react-cookies library (npm install react-cookies)
Inside of the component which triggers the POST request, declare the following:
const cookies = useCookies(['XSRF-TOKEN']);
Pass 'cookies' to your function which facilitates the fetch request - For me this was simply called 'signUp' and was called inside my handleSubmit() method.
const handleSubmit = (event) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
signUp(data.get("firstName"), data.get("mobileNumber"), data.get("email"),
data.get("password"), setUser, cookies['XSRF-TOKEN'] );
}
My fetch request inside of signUp() looks like the following:
await fetch(`/register`, {
headers: {
"X-XSRF-TOKEN": token,
"Content-Type": 'application/json'
},
credentials: 'include',
method: "POST",
body: JSON.stringify(customerData),
});
I'm sure this isn't the cleanest, nor the most practical way to do this and I hope someone is willing to shed further clarity if this is the case.
This was posted on the basis that I struggled to find a solution and hope this may be of some use/help going forwards.

FastAPI: React native frontend giving 422 error during auth flow

My react native code:
const signin =
(dispatch) =>
async ({ username, password }) => {
try {
console.log(username, password);
const response = await tracker.post(
"/login",
(data = { username, password }),
(headers = {
"content-type": "application/x-www-form-urlencoded",
})
);
await AsyncStorage.setItem("token", response.data.token);
dispatch({ type: "signin", payload: response.data.token });
console.log(response.data.token);
} catch (err) {
console.log(err);
dispatch({
type: "error",
payload: "This is an error, start debugging",
});
}
};
Curl request to FastAPI backend:
curl -X 'POST' \ 'https://fastest.herokuapp.com/login/' \ -H 'accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=&username={email}&password={password}&scope=&client_id=&client_secret=
whenever I try to create a new user or sign in with an existing user I keep getting following error:
[AxiosError: Request failed with status code 422]
Is there a better way to send a POST request with curl to signup or login using axios?
Now, I know this is a well documented error on internet, but, somehow, I am unable to find the error and debug it. Any feedback as to what I am doing wrong?
Edit:
FastAPI endpoint code:
#router.post("/",response_model=schemas.Token)
def getLogin(user_Credentials:OAuth2PasswordRequestForm=Depends(),db: Session=Depends(database.get_db)):
user = db.query(models.User).filter(models.User.email == user_Credentials.username).first()
if not user:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=f"wrong credentials")
if not utils.verify(user_Credentials.password,user.password):
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=f"wrong credentials")
access_token = oauth2.create_access_token(data={"user_id": user.id})
return {"access_token":access_token, "token_type":"bearer"}
For full code:
Backend FastAPI: here
Frontend react native: here
Error Changed
After adding qs.stringify() according to https://axios-http.com/docs/urlencoded and updating the code as follows:
const signin =
(dispatch) =>
async ({ username, password }) => {
try {
console.log(username, password);
const response = await tracker({
method: "post",
url: "/login",
data: qs.stringify({
username: username,
password: password,
}),
headers: {
"content-type": "application/x-www-form-urlencoded;charset=utf-8",
},
});
console.log(response.data.token);
await AsyncStorage.setItem("token", response.data.token);
dispatch({ type: "signin", payload: response.data.token });
} catch (err) {
console.log(err);
dispatch({
type: "error",
payload: "Start debuggin",
});
}
};
the problem arises now is that token is undefined, but the when I enter same credentials on /docs I get the token.
Final update: got the endpoint wrong for token access
As per Javascript documentation:
A variable that has not been assigned a value is of type undefined.
A method or statement also returns undefined if the variable that is
being evaluated does not have an assigned value. A function returns
undefined if a value was not returned.
In your case, you attempt to retrieve an attribute, namely token, from the JSON repsonse returned by your FastAPI backend. However, such an attribute does not exist in that JSON object. Your API endpoint returns "access_token": access_token, hence, you should instead use response.data.access_token.
Also, for future reference, a response having status code 422 (unprocessable entity) will have a response body that specifies the error message, telling exactly which part of your request is missing or doesn’t match the expected format. This will guide you to fix the error in your code.
Please try to send your authentication data as FormData.
let bodyFormData = new FormData();
bodyFormData.append("username", "value");
bodyFormData.append("password", "value");
then send it as you did:
const response = await tracker.post(
"/login",
(data = bodyFormData),
(headers = {
"content-type": "application/x-www-form-urlencoded",
})
);
It should be mentioned that I didn't do much with react-native, but I guess this work for your case.

issue with making a call using fetch and jwt

*My goal here is to get the location of bikes from a bike-sharing company's API.
I did Steps 1 and 2 using Postman. but ill try to integrate it into my code once I get the hang of it.
The first step is to verify your email and generate an Auth token. This requires only a verifiable email address. Make a POST request to https://web.spin.pm/api/v1/magic_links with the body:
{"email": "sampleemail#gmail.com"}
From there, you will need to find the token within your email. This token needs to be sent with a POST request to
https://web.spin.pm/api/v1/auth_tokens with the body:
{
"grant_type": "magic_link",
"magic_link": {
"email": "<email>",
"token": "<token>"
}
}
This request returns a JSON that looks like this: {"jwt":"eyJ0eXAiOiJ.....cXVLw","refreshToken":"2cb07....bab5030","existingAccount":false}
To get the position of vehicles so a GET-Request to https://web.spin.pm/api/v3/vehicles?lng=-77.0146489&lat=38.8969363&distance=&mode= User Header Authorization: Bearer to Authenticate and use the jwt-Token we got from the Auth request.
You will get something like this as return JSON {"vehicles":[{"lat":37.69247,"lng":-122.46595,"last4":"3595","vehicle_type":"bicycle","batt_percentage":null,"rebalance":null}, … ]}
Step 3 is done using (async/awit function) using fetch where I am having the problem with. I copy-pasted the jwt in my .env file and set up the proper headers.
I get a 401 response when making the call. when I tested step 3 using postman everything seems to work fine.
I have attached a screenshot of the error in this post. Hopefully its more clear, Thanks in advance.
const fetch = require("node-fetch");
require('dotenv').config();
async function getBikes()
{
const lat = '38.897574612438575';
const lng = '-77.01855164084469';
const api_url = `https://web.spin.pm/api/v3/vehicles?lng=${lng}&lat=${lat}&distance=&mode=`;
const jwt_key = process.env.BERER_KEY;
try{
const config = { method: 'GET',
headers: {json: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer'+ jwt_key
} },
rejectUnauthorized: false
};
const response = await fetch(api_url,config );
const data = await response.json(); //response.json() //headers //.jwt; //response.json()
if (response.ok)
{
console.log("STATUS CODE IS: "+response.status);
console.log('My JWT:', response);
return data;
}
else{
console.log("something went wrong ");
console.log("STATUS CODE IS: "+ response.status);
console.log( response);
}
} catch (error) {
console.log(error);
}
}
const y = getBikes();
console.log(y)
BEARER_KEY=eyJhbGciOiJIUzI1NiJ9.eyJ1c2V

Console log data got from graphql api

I have the following method from my vuex action block where I send user email and password to backend server and get userId and token on success.
async signIn ({ commit }, formData) {
const graphqlQuery = {
query: `
query{
loginData(
email: "${formData.email}",
password: "${formData.password}"
) {userId, token}
}
`
}
const res = await this.$axios.post('http://localhost:8080/graphql', graphqlQuery, {
headers: {
'Content-Type': 'application/json'
}
})
console.log(res.data) //works
console.log(res.data.loginData.token) //doesn't work
commit('loadUserData', true, res.data.loginData.token, res.data.loginData.userId)
return res.status
}
I can confirm that I'm getting the response data with console.log(res.data). The response data I get is:
But when I console.log(res.data.loginData) I get undefined. And blank on console.log(res.data.loginData.token) and console.log(res.data.loginData.token).
How do I extract the required data token and userId ?
I'm using webstorm as my IDE and it shows loginData as method refering to my backend graphql resolver method.
My frontend is made on Nuxt js, backend on node js with graphql.
Does anyone have any idea to overcome this issue ?

Feedly API is returning session expired instead of letting me access the API from local node environment

Using feedlys api with a node wrapper suggested from feedly to access its api. I am not getting successful logins. I have scoured the docs and any resources available and cannot find any answers so I'm reaching out to the stack overflow community to see if anyone has had experience with this platform.
I tried clearing the cache. I've tried using the fetch api instead of using the node wrapper I am trying to implement.
I installed the node package 'feedly'.
added this code to my server:
const Feedly = require('feedly')
const f = new Feedly({
client_id: 'client_id here',
client_secret: 'client_secret here',
base: 'https://cloud.feedly.com/v3/collections/',
port: 8080
})
async function feedlyStream() {
const results = await f.reads()
return console.log('results', results)
}
feedlyStream();
It does take me to a page to log in, presumably this is the auth so then i can retrieve data.
I'm not a backend user and primarily front end so performing the task this way is new to me.
When i run nodemon ./server.js from the console, it takes me to a login page, like that of feedlys website but then I get the error 'session expired'. There is no other errors, not in the console etc.
I can get retrieve information when working with insomnia to test the api endpoints, with the same exact info as above plus a bearer token.
Here is the fetch version i have tried with is very similar to that of the insomnia input.
const URL = 'https://cloud.feedly.com/v3/collections/'
const proxyurl = "https://cors-anywhere.herokuapp.com/";
window.onload = () => {
fetch(proxyurl + URL, {
credentials: 'same-origin',
Accept: 'application/json',
headers:
{
'Authorization': 'Bearer TOKEN GOES HERE',
'Access-Control-Allow-Origin': 'include',
'Content-Type': 'application/json',
"client_id": "client_id here",
"method": "GET",
"client_secret": "client_secret here",
}
})
.then(function (data) {
console.log('data from api', data.body);
const here = document.getElementById("here")
const bodyText = () => {
if (data.body == null) {
return "Nope, it's null"
}
return data.body;
}
here.innerHTML = bodyText();
})
}
This is what i receive from the console log above
data from api ReadableStreamlocked: false__proto__: ReadableStream
Any help will be greatly appreciated. Thank you.
quite simply i was missing part of the fetch. I needed to transform the response into JSON. Not use to fetch or apis still and this was an obvious but annoying one.
"method": "GET",
"client_secret": "client_secret here",
}
})
.then(res => res.json();) // this is what i needed to add in :)
.then(function (data) {
console.log('data from api', data.body);

Categories