我最近了解了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:
所示放置了setSigningKeyClaims claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(apiKey.getSecret())).parseClaimsJwt(jwtString).getBody();.
上述代码无效,原因有两个: 我没有图书馆 import javax.xml.bind.DatatypeConverter; 我不知道怎么拿钥匙。
但是知道我不需要密钥,因为这次我尝试登录并收集用户信息(如名字,姓氏,电话等)和签名(令牌)所以我下次将数据发送到服务器端时,我有令牌来访问后端。
有人可以帮助我吗?
答案 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进行签名,并使用公钥在设备上进行验证。
- 我没有库导入javax.xml.bind.DatatypeConverter
醇>
String base64 = Base64.encodeToString(data, Base64.DEFAULT);
byte[] data = Base64.decode(base64, Base64.DEFAULT);
- 我不知道怎么拿钥匙。
醇>
您的密钥可能是以这种方式在服务器端生成的
Key key = MacProvider.generateKey(SignatureAlgorithm.HS256);
byte data[] = key.getEncoded();
以您喜欢的方式向客户提供密钥data[]
。使用不对称密钥,您只需要提供公钥。
KeyPair keyPair = RsaProvider.generateKeyPair();
byte data[] = keyPair.getPublic().getEncoded();