Json Web 令牌 - jose4j - SyntaxError:JSON 中位置 0 的意外令牌 e

Posted

技术标签:

【中文标题】Json Web 令牌 - jose4j - SyntaxError:JSON 中位置 0 的意外令牌 e【英文标题】:Json Web Token - jose4j - SyntaxError: Unexpected token e in JSON at position 0 【发布时间】:2017-02-10 22:08:38 【问题描述】:

我有一个试图获取令牌的控制器。

当我在视图 PRETTY 中执行它时,我在邮递员中收到此错误

意外的“e”

但如果我去查看 RAW,我可以看到这样的令牌。

eyJraWQiOiIxIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJJc3N1ZXIiLCJhdWQiOiJBdWRpZW5jZSIsImV4cCI6MTQ3NTQ1OTMyNiwianRpIjoiTmF3d000bDVGRmFRZ0dBQkwzS3N5USIsImlhdCI6MTQ3NTQ1ODcyNiwibmJmIjoxNDc1NDU4NjA2LCJzdWIiOiJzdWJqZWN0IiwiZW1haWwiOiJtYWlsQGV4YW1wbGUuY29tIn0.f97SFDaAjUyUDK_UQgwgnCTewd0yw6tWK6DFLzpALFq177f1QMTYPbVdiIG1ViJ0FNJ6fUCleCd8BmrToUn25VSmRv799dtcz-xaN1kOgw90NQ00kPUhnDXG01-7hImkHfbmZZWORukP2yPK1sHWzpdjg9fJOvRZpZ6ZWli4HeuYRJqsFOv7PvwmGH9JnfRTf_2tboL-oAYBpT367eh60TggrvMgmrO_Taj5M7qGG0GpbwuVh_HTAkaKv7T2WmuZ2JPANhe5JvY_DDaqChtwd0IPREAhK3Xr-nTOIuwbQ0Y1hhOGfvDmikQj6DXnCERYixP6eR1dhC8n3bKvXyaVmA

这是我的控制器的代码。

@Path("/demo")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response testMethod() throws JSONException, IOException 
    RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
    rsaJsonWebKey.setKeyId("k1");
    JwtClaims claims = new JwtClaims();
    claims.setIssuer("Issuer");  
    claims.setAudience("Audience");
    claims.setExpirationTimeMinutesInTheFuture(10);    
    claims.setGeneratedJwtId(); 
    claims.setIssuedAtToNow();
    claims.setNotBeforeMinutesInThePast(2); 
    claims.setSubject("subject"); 
    claims.setClaim("email","mail@example.com"); 
    JsonWebSignature jws = new JsonWebSignature();

    jws.setPayload(claims.toJson());
    jws.setKey(rsaJsonWebKey.getPrivateKey());
    jws.setKeyIdHeaderValue(rsaJsonWebKey.getKeyId());

    jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);

    String jwt = jws.getCompactSerialization();
    if(jwt == null)
        return Response.status(204).entity(jwt).build();
    
    return Response.status(200).entity(jwt).build();

我忽略了邮递员中的错误,但尝试在 Chrome 中执行它时出现同样的错误。

我尝试用这样的角度调用我的 RESTful 控制器,但我总是使用响应参数中的消息进入 onError 方法。

angular.min.js:118 SyntaxError: Unexpected token e in JSON at position 0

这是 Angular 中的代码

app.service('TokenService', function($http)
    this.getToken = function()
      function onSuccess(response)
          console.log('got it');
      

      function onError(response)
          console.log('fail');
      

      return $http(
          method : 'GET',
          url : 'http:localhost:8080/rest/demo',
          header: 'Content-Type' : 'application/json'
      ).then(onSuccess, onError);
    

我对令牌代码的引用来自 here 和 Jose4j

更新

我解决了这个问题。我仍然认为我最初的方式应该也可以工作,但我仍然不明白为什么会出现错误。

我创建了一个名为 Token 的 pojo,其属性标记为 String,然后我更改了它

return Response.status(200).entity(jwt).build();

到这里:

Token token = new Token();
token.setToken(jwt);
return Response.status(200).entity(token).build();

这是我返回真实 json 对象的解决方法。

【问题讨论】:

乍一看,您似乎没有在 API 响应中返回 JSON,而是一个 RAW 字符串。 看起来但是这个 Response.status(200).entity(jwt).build() 正在做它的工作 【参考方案1】:

我知道现在为时已晚,但我遇到了同样的问题并用您的解决方案解决了它,所以谢谢。

只是为了以后遇到这个问题的人。就我而言,我是这样做的。

HashMap<String, String> credential = new HashMap<>();
credential.put("token", jwtToken);
apiResp = ResponseEntity.ok(jwtToken);

顺便说一句,我似乎也发现了问题,Angular 可能期望服务器的响应默认是 JSON 对象,然后为我们将其解析为 javascript 对象。 所以我们得到了错误,因为我们将字符串作为响应实体返回,并且它无法将字符串解析为对象。这就是为什么将令牌放入 POJO 解决它的原因。

另一种方法是像这样从客户端设置返回类型。

login(username: string, password: string): Observable<any> 
    let body = username, password;
    let res = this.http.post(
      `$API.AUTHENTICATION`, body, 
        responseType: 'text'
      );
  
    return res;
  

现在,JS 会知道响应是字符串类型,它不会再尝试将其解析为对象。

【讨论】:

以上是关于Json Web 令牌 - jose4j - SyntaxError:JSON 中位置 0 的意外令牌 e的主要内容,如果未能解决你的问题,请参考以下文章

使用由 jose4j 生成的令牌在 node.js 中使用 jsonwebtoken 验证 JWT 失败

Web Api中的JSON Web令牌与承载令牌

Json Web 令牌不会过期

生成 JSON Web 令牌

用于用户身份验证的个人访问令牌和 json Web 令牌有啥区别?

使用 JWT(JSON Web 令牌)设置令牌到期的 RESTful API