Я использую password.js с jwt для аутентификации пользователей в моем приложении. Я подписываю токен jwt, используя полезную нагрузку, которая среди других полей содержит поле аватара, чтобы использовать аватар во всем моем приложении. Теперь я хочу, чтобы пользователи могли редактировать свой аватар. Я реализовал эту функцию и отлично работает с одной проблемой: несмотря на то, что поле аватара обновлено в mongodb, изменения отображаются в приложении только после того, как я выйду из системы и снова войду в систему. (После повторной подписи токена)
Во внешнем интерфейсе я использую react + redux.
Как мне правильно обновить это поле аватара, учитывая, что это часть полезной нагрузки? Стоит ли использовать другой подход?
Код ниже:
Вход в систему ниже:
User.findOne({ email: email }).then(user => {
if (!user) {
return res.status(404).json({
email: "Couldn't find an account."
});
} else {
bcrypt.compare(password, user.password).then(isMatch => {
if (isMatch) {
//User matched
//Create JWT Payload (can contain any user info)
const payload = {
id: user.id,
firstname: user.firstname,
lastname: user.lastname,
email: user.email,
avatar: user.avatar
};
//Sign token
//The sign method from jwt needs a payload(user info), secret and optional expiration date
//This token is needed so the user can access private routes or any other private logic
jwt.sign(
payload,
keys.secretOrKey,
{ expiresIn: "1d" },
(err, token) => {
res.json({
success: true,
token: "Bearer " + token
});
}
);
} else {
return res
.status(400)
.json({ password: "Eroare! Parola incorecta!" });
}
});
}
});
});
Действие Redux:
// Login
export const loginUser = userData => dispatch => {
axios
.post("/api/users/login", userData)
.then(res => {
//Save to localStorage
const { token } = res.data;
//Set token to localStorage
localStorage.setItem("jwtToken", token);
// Set token to Auth Header
setAuthToken(token);
// Decode token
const decoded = jwt_decode(token);
// Set current user
dispatch(setCurrentUser(decoded));
})
.catch(err => {
dispatch({
type: GET_ERRORS,
payload: err.response.data
});
});
};
//Set logged in user
export const setCurrentUser = decoded => {
return {
type: SET_CURRENT_USER,
payload: decoded
};
};
Редуктор:
const initialState = {
isAuthenticated: false,
user: {},
loading: false
};
export default function(state = initialState, action) {
switch (action.type) {
case USER_LOADING:
return {
...state,
loading: true
};
case SET_CURRENT_USER:
return {
...state,
isAuthenticated: !isEmpty(action.payload),
user: action.payload
};
default:
return state;
}
}
Можете ли вы поделиться с нами кодом компонента, когда отображается аватар и из него вызывается действие входа в систему?
@HoangTrinh Вот что помогло мне решить эту проблему. Отправьте ответ, и я его одобряю.
@OvidiuG: Спасибо, что сообщили мне, я опубликовал ответ.





В основном в полезной нагрузке токена JWT есть информация, которая полезна для вашего кода внешнего интерфейса, такая как электронная почта, имя пользователя, аватар, ...
Но поскольку токен JWT может быть проверен только и должен быть выпущен только на сервере (он может быть декодирован только во внешнем интерфейсе, потому что интерфейс не знает секрет JWT), поэтому всякий раз, когда вам нужна новая информация в полезной нагрузке JWT, вам нужно выпустить новый токен на сервере.
Применительно к вашей ситуации вам необходимо выпустить новый токен JWT после обновления аватара и отправить обратно токен JWT в ответ API updateAvatar.
После этого вы можете обновить localStorage новым токеном JWT и получить свой новый аватар во внешнем интерфейсе.
Я думаю, вы можете подписать новый токен JWT после того, как пользователь изменит аватар, и отправить его обратно в ответ API updateAvatar. Затем во внешнем интерфейсе вы обновляете localStorage этим новым токеном