如何从Android上的JWT收集签名,标题和正文

时间:2016-06-14 08:02:12

标签: java android web-services jwt

我最近了解了Json Web Token(JWT)。由于我喜欢它的工作方式,我已经开始在我的项目中实现它了。我的项目涉及两个沟通的应用程序。一个是Android应用程序,另一个是Laravel Web应用程序。

移动应用程序在从服务器端验证用户凭据后登录。

我已经从移动应用程序向服务器发送了用户名和密码,我已经获得了字符串格式的JWT。但从这一点开始,我无法找到收集JWT内容的方法。

我已经完成了几乎所有可能的显示(谷歌搜索结果),但我无法获得内容,签名和标题。

我进一步了解的方法之一是使用以下代码,注意我已经删除了setSigningKey():

try {
  Claims claims = Jwts.parser().parseClaimsJwt(jwtHeaderAndClaim).getBody();
  System.out.println("ID of the claims: " + claims.getId().toString());
  }catch (Exception e){
    Log.e("Exception: ", e.toString());
}

以上代码生成以下错误:

Exception: io.jsonwebtoken.PrematureJwtException: JWT must not be accepted before 2016-06-14T10:20:09+0300. Current time: 2016-06-14T10:19:37+0300´ 

jwtHeaderAndClaim是仅删除签名部分后的JWT字符串(即:" xxxxxx.yyyyyyyyy。")。如果我把jwtString(xxxxxxx.yyyyyyyy.ccccccc)代替jwtHeaderAndClaim,将发生以下错误:

Exception: io.jsonwebtoken.UnsupportedJwtException: Signed JWSs are not supported

如果我按照stormpath example

所示放置了setSigningKey
Claims claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(apiKey.getSecret())).parseClaimsJwt(jwtString).getBody();. 

上述代码无效,原因有两个: 我没有图书馆     import javax.xml.bind.DatatypeConverter; 我不知道怎么拿钥匙。

但是知道我不需要密钥,因为这次我尝试登录并收集用户信息(如名字,姓氏,电话等)和签名(令牌)所以我下次将数据发送到服务器端时,我有令牌来访问后端。

有人可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

你有很多问题。我试着回答其中一些

  

io.jsonwebtoken.PrematureJwtException:之前不得接受JWT   2016-06-14T10:20:09 + 0300。当前时间:2016-06-14T10:19:37 + 0300'

您在JWT中使用nbf(not before)属性。不要使用它(它是可选的)或设置有效范围,因为设备的时钟不会同步

来自RFC 7519

  

“nbf”(不是之前)声明标识JWT之前的时间   绝不接受处理。处理“nbf”索赔要求当前日期/时间必须等于或等于“nbf”索赔中列出的不在前日期/时间。 实施者可以提供一些小的余地,通常不超过几分钟,以解决时钟偏差问题。它的值必须是包含NumericDate值的数字。 使用此声明是可选的。

签名JWS

  

异常:io.jsonwebtoken.UnsupportedJwtException:已签名的JWS是   不支持

您想在客户端或服务器端验证签名密钥吗? 如果您使用JWT进行身份验证,请替换user&密码,并且您在每个请求中发送令牌,您可以在服务器端验证签名。

如果您想验证应用程序上的密钥,请不要使用对称密钥,因为如果它落入坏人之手,它可能是一个很大的漏洞。 See。您可以使用和非对称密钥对。使用私钥在服务器中对JWT进行签名,并使用公钥在设备上进行验证。

  
      
  1. 我没有库导入javax.xml.bind.DatatypeConverter
  2.   
String base64 = Base64.encodeToString(data, Base64.DEFAULT);
byte[] data = Base64.decode(base64, Base64.DEFAULT); 
  
      
  1. 我不知道怎么拿钥匙。
  2.   

您的密钥可能是以这种方式在服务器端生成的

 Key key = MacProvider.generateKey(SignatureAlgorithm.HS256);
 byte data[] = key.getEncoded();

以您喜欢的方式向客户提供密钥data[]。使用不对称密钥,您只需要提供公钥。

 KeyPair keyPair = RsaProvider.generateKeyPair();
 byte data[] = keyPair.getPublic().getEncoded();