my jwt token is sometimes recievable, or not recievable - reactjs

I'm practicing login using react and node.js. but have a problem. My jwt token is not receivable from backend.
I watched the video on YouTube and followed it. link is here (sadly the youtuber doesnt have code in github:()
I think nodejs code doesn't have any problem. because I checked token by console.log no matter client receive token or not.
export const loginUser = (email, password) => async dispatch => {
try {
const config = {
headers: {
'Content-Type' : 'application/json'
}
}
const body = JSON.stringify({email, password})
const response = await axios.post('http://localhost:4000/app/signin', body, config)
dispatch({
type: LOGIN_SUCCESS,
payload: response.data
})
dispatch(loadUser());
} catch (error) {
dispatch({ type: LOGIN_FAIL, payload: error })
}
}
I receive token using this code, it sometimes bring token or not. I also use async and await, but the problem always happen. When I use console.log to check response data it says undefined.
I checked code but think there is no mispelled.
I'm also using redux to login. weirdly, when I try to login, it appears new tab exatly same login page. The problem also happening irregularly. And I use redux extensional devtools with chrome. When I try to login, redux states always initialized.
I have no idea why this happening. And when I failed to login, beginning append with '?' after url. like this.
I know it's hard to guess why this happening.
To see my code detail
Thank you for read this.

Related

Redirect 401 Error in React Redux Actions File

So I'm trying to redirect the user if the server responds with a 401 Unauthorized response based on the user authentication backend I've established. Currently I'm sending a request to the server to check if the user matches with the item I'm checking against. IF they don't match, a 401 Unauthorized response is returned. But I cannot properly redirect them in my .catch(err) statement in my actions file.
I've tried several different solutions, stackoverflow searches, google searches, tutorials, and still cannot get the results I want. I've also tried installing different packages to no avail.
Here is my actions file. The .catch(err) is where I'd like to redirect the user to if a 401 error comes back.
// Get Single Score
export const getScore = (id, history) => dispatch => {
dispatch(setScoreLoading());
axios
.get(`score/${id}`)
.then(res =>
dispatch({
type: GET_SCORE,
payload: res.data
})
)
.catch(err =>
dispatch({
type: SCORE_NOT_FOUND,
payload: err.response.data
})
history.push('/not-authorized')
);
}
Any help is greatly appreciated.
i think the problem is your arrow function . you use => directly that will return your dispatch but never touch your history.push
.catch(err => {dispatch({
type: SCORE_NOT_FOUND,
payload: err.response.data
})
return history.push('/not-authorized')
)}
Hope this help.
Btw use history.replace is better in this case in my opinion

How to create logout when expires token

could someone help me to resolve this problem?
I don't know how to implement expired session to my react app.
I have json data with expires_in: 86400 what I need to do to implement this to my app, when expired to logout user.
I using react.JS and redux.
Action:
export const signin = obj => {
return dispatch => {
let data = {
method: "post",
url: "/oauth/token",
data: {
grant_type: "password",
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
username: obj.email,
password: obj.password
}
};
return API(data)
.then(res => {
window.localStorage.setItem("access_token", res.data.access_token);
console.log('uuuuuuuuuu', res)
dispatch({
type: AUTH.LOGGED_IN,
payload: {
access_token: res.data.access_token,
expired_in: res.data.expires_in
}
});
})
.catch(err => {
throw err;
});
};
};
You can simply achieve this using setTimeout function to trigger your logout functionality. The below code is on the assumption that expires_in is the relative time not the absolute time.
window.localStorage.setItem("access_token", res.data.access_token);
setTimeout(logoutFunction, response.data.expires_in)
console.log('uuuuuuuuuu', res)
dispatch({
type: AUTH.LOGGED_IN,
payload: {
access_token: res.data.access_token,
expired_in: res.data.expires_in
}
});
and your logoutFunction will look something like this:
function logOutFunction() {
window.localStorage.removeItem("access_token");
// your redux dispatch and probably a redirection logic to go to a proper UX page
}
I mistakenly said in comments to use setInterval. I assume this will be a one time execution, setTimeout is better to use.
From your code I found. you have used window.localStorage.setItem("access_token", res.data.access_token);
But you actually need a cookie there and set the expire time from the response. Then you have to check is that the cookie existence in the parent component. if it, not exist (expired) you can redirect to the login page.
For force logout, you can simply make the cookie expire. ;)
You shouldn’t store the time left to expire, but the current time + the time left. Otherwise you can’t know when this happened.

spotify api axios react post request 403 error

makePlaylist = event => {
event.preventDefault()
let token = localStorage.getItem('token')
let playlist = {name: this.state.text, public:false}
axios.post(
`https://api.spotify.com/v1/users/${this.state.user_id}/playlists`, playlist,
{headers: {
"Authorization": 'Bearer ' + token
}
}
)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
}
and I get the following error
https://api.spotify.com/v1/users/my_user_id_here/playlists 403 error
I looked up the documentation online at
https://developer.spotify.com/documentation/web-api/reference/playlists/create-playlist/
and it looks like I'm setting things up as far as I can tell. Anyone know what I'm doing wrong with the request? I know the access token is valid.
"Trying to create a playlist when you do not have the user’s authorization returns error 403 Forbidden." Make sure that the Spotify app that you made in Dashboard has the proper scope permissions on the user you are trying to create the playlist for. Here is the scope for creating a private playlist: https://developer.spotify.com/documentation/general/guides/scopes/#playlist-modify-private
Here is the tutorial for setting up authorization with passing in a scope:
https://developer.spotify.com/documentation/general/guides/authorization-guide/

Redux Post Request failed with status code 404

I am trying to do a request to my local host on my network in a redux app with axios.
here is the request code :
export function createAccount(userInfo){
return async (dispatch) => {
try {
const resp = await axios.post(`${BASE_URL}/signup`, userInfo);
localStorage.setItem('token', resp.data.token);
dispatch({ type: types.SIGN_UP });
} catch(err) {
console.log('Sign Up Error:', err.message);
}
}
}
And here is what error is displayed :
Sign Up Error: Request failed with status code 404
Another possible cause may be mismatch between the names of the sent parameters and the expected on the REDUX end (actions). Better provide the code for the reducers and the action index. In my case I got 404 on POST request and when I checked the Headers (under Network) I figured out that the Request Payload is empty. The reason was the following:
const data = {
linkIdCampaign,
linkIdMix
}
this.props.onAddLink(data);
on the front end part did not correspond to the:
return axios.post("http://localhost:5000/YOUR_URL", { newLink, newMix})
.then(response => {
in the actions index.

Best practice to handle redux + axios API request actions

So my scenario is like this:
I have 2 types of requests: "public" requests which don't require authorization information, and "authorized" requests which do.
For authorized requests, before actually sending every request I must put auth info into the header. After the request finishes, the new access token returned from the server should be saved into the state.
So a lot of my actions currently looks like this:
export const asyncAction = (id) => async (dispatch, getState) => {
const { auth } = getState()
const config = {
headers: {
"access-token": auth["access-token"],
"client": auth.client,
"uid": auth.uid
}
}
const request = await axios.get(`${API_URL}`, config)
dispatch({ type: UPDATE_USER_ACCESS_TOKEN, payload: request})
dispatch({ type: ANOTHER_ACTION, payload: request.data })
}
I did some research and there are 2 possible ways to do this: Axios interceptor, or write a Redux middleware.
I feel like Axios interceptor, at least for the response part, is not the best solution here as it is intended to just do something with the response data, while I need to dispatch another action after I complete updating the new access-token, and I don't want to export the store to manually dispatch my actions, which is an anti-pattern. (as I mentioned the flow is: putting auth info into headers => send request => if it succeeds, then save the new access-token to Redux store for later use, then dispatch other actions; if it fails, do some error handlings).
Then I found this lib but I think I'm too dumb to understand the documentation:
https://github.com/svrcekmichal/redux-axios-middleware
Can someone please give me an example of how to do this? Both using that lib and writing custom middleware from scratch are fine for me. Thanks!

Resources