更新存储在 jwt 有效负载中的字段

Posted

技术标签:

【中文标题】更新存储在 jwt 有效负载中的字段【英文标题】:Update field stored in jwt payload 【发布时间】:2019-01-16 19:20:38 【问题描述】:

我正在使用带 jwt 的 passport.js 来验证我的应用程序中的用户。我正在使用包含其他字段(包括头像字段)的有效负载对 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;
  

【问题讨论】:

我猜你可以在用户更改头像后签署新的 JWT 令牌,并在 updateAvatar API 的响应中将其发回。然后在前端,使用这个新令牌更新 localStorage 你能分享给我们显示头像的组件代码和调用登录操作的组件代码吗? @HoangTrinh 这就是帮助我解决这个问题的原因。发布一个答案,我会批准它。 @OvidiuG:谢谢你让我知道,我发布了答案。 【参考方案1】:

基本上在 JWT 令牌的有效负载中,有一些对您的前端代码有用的信息,例如电子邮件、用户名、头像……

但是因为 JWT 令牌只能被验证并且只能在服务器上发布(它只能在前端解码,因为前端不知道 JWT 秘密),所以每当您需要 JWT 有效负载中的新信息时,您需要在服务器上发布新令牌。

适用于您的情况,您需要在更新头像后发布新的 JWT 令牌,并在 updateAvatar API 的响应中发回 JWT 令牌。

之后,您可以使用新的 JWT 令牌更新 localStorage 并在前端获取您的新头像。

【讨论】:

以上是关于更新存储在 jwt 有效负载中的字段的主要内容,如果未能解决你的问题,请参考以下文章

JWT 从 node.js 更新有效负载

JWT 有效负载中的令牌

没有任何 JS 访问令牌的 JWT 有效负载加密

在验证之前使用 JWT 有效负载

python jwt中令牌过期时如何提取jwt令牌有效负载

Flask JWT 令牌/有效负载 - 返回用户 Json