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",
});
}
};
FastAPI curl:
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 post the curl with signup or login data 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 fast api:https://github.com/bhavyasharma95/FastAPI-quickstart front end react native:https://github.com/bhavyasharma95/Reactnative-Quickstart
Error Changed
After adding qs.stringify according to https://axios-http.com/docs/urlencoded and updating the code as follow:
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
CodePudding user response:
As per Javascript documentation:
A variable that has not been assigned a value is of type
undefined
. A method or statement also returnsundefined
if the variable that is being evaluated does not have an assigned value. A function returnsundefined
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.
CodePudding user response:
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.