三行代码  ›  专栏  ›  技术社区  ›  koque

为什么jsonwebtoken声明我的令牌无效?

  •  0
  • koque  · 技术社区  · 3 周前

    在客户端上,我有以下函数,它调用服务器api来注册用户。返回用户令牌并将其放入本地存储中。

      public register = (user) => {
        this.httpClient.post<User>(this.url, user).pipe(
          tap(userData => {
            console.log('userData register.userData', userData)
            localStorage.setItem('userToken', JSON.stringify(userData.token));
            // this.router.navigate(['/home']);
          })
        ).subscribe(),
        catchError(error => {
          console.log('error', error)
          this.store.dispatch(messageActions.SetError({error}))
          throw error;
        })
      }
    

    令牌的副本如下所示:

    “eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTRkNzc4MzFkMGUxN2ZiZTI1MDMyM2EiLCJpYXQiOjE2OTk1NzU3ODQsImV4cCI6MTY5OTU3NU4NH0.3HsdFjARnAjWn35_VlXsJQ6oFbfL_3OLHTTPsroIoayU”

    拦截器将令牌附加到服务器的每个请求的标头中,如下所示:

    intercept(request: HttpRequest<unknown>, next: HttpHandler): 
    Observable<HttpEvent<unknown>> {
       const token = localStorage.getItem('userToken');
       console.log('token', token)
    
       if(token) {
        // const authReq = req.clone({setHeaders:{token:token}});
    
        const authReq = request.clone({setHeaders:{"Authorization":"Bearer " + token}});
    
        console.log('authReq', authReq)
        return next.handle(authReq)
    }
    
        return next.handle(request);
      }
    }
    

    以下是服务器端与创建令牌相关的精简代码:

    exports.register = async (req, res) => {
        try {
            let userData = {};
            userData.token = generateAccessToken(newUser._id);
            userData.cart = cart;
    
           console.log("userData", userData);
    
            return res.status(201).json(userData)
    
        } catch (error) {
            console.log(error);
            res.status(500).send('Problem signing up user!')
            // throw error;
    
        }
    };
    
    
    function generateAccessToken(userId) {
        return jwt.sign({ userId }, process.env.JWT_SECRET, { expiresIn: '1800s' });
    }
    
    function authenticateToken(req, res) {
        const authHeader = req.headers.authorization
        console.log('authHeader', authHeader)
        const token = authHeader && authHeader.split(' ')[1]
        console.log('token', token)
    
        try {
            if (token == null) return res.status(500).send('Problem authenticating user token.')
    
             const {
                userId
            } = jwt.verify(token, process.env.JWT_SECRET)
    
            return userId;
        
       } catch(err) {
           console.log(err);
            res.status(500).send('Problem authenticating user token.')
        }
    }
    

    这是从拦截器传输到服务器的令牌的副本。(当然,“熊”是脱光的。

    “eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTRkNzc4MzFkMGUxN2ZiZTI1MDMyM2EiLCJpYXQiOjE2OTk1NzU3ODQsImV4cCI6MTY5OTU3NU4NH0.3HsdFjARnAjWn35_VlXsJQ6oFbfL_3OLHTTPsroIoayU”

    authenticateToken函数在调用jwt.verify时出错,并显示消息:Invalid token。

    2 回复  |  直到 3 周前
        1
  •  1
  •   Phil    3 周前
    localStorage.setItem('userToken', JSON.stringify(userData.token));
    

    您正在使用 JSON.stringify() 存储令牌,但不使用 JSON.parse() 检索时。

    它将嵌入 " 包装实际令牌的字符。

    const token = "my-jwt-token";
    
    console.log("compare");
    console.log({ Authorization: `Bearer ${token}` });
    console.log({ Authorization: `Bearer ${JSON.stringify(token)}` });

    考虑到令牌只是一个字符串,我不会去打扰 JSON.stringify()

    localStorage.setItem('userToken', userData.token);
    
        2
  •  -1
  •   Sajan Dhakal    3 周前
      const payload = {
        userId,
        iat: moment().unix(),
        exp: expires.unix(),
      };
    
     jwt.sign(payload, secret);