我正在 iOS (7) cient 端实现 JSON Web Token 身份验证。它运作良好。我的应用程序接收令牌,并且可以使用它们对我的服务器进行经过身份验证的调用。
现在,我希望我的客户端代码检查令牌上的到期日期,以便知道何时重新进行身份验证。检查 JWT 身份验证令牌的到期日期很简单。授权令牌是 3 个 base64 编码的 JSON blob,用“.”分隔。- 过期时间戳位于中间 blob 中的一个名为ext
. 自 unix 时代以来已经过了几秒钟。
所以我的代码看起来像这样:
- (NSDate*) expirationDate
{
if ( !_tokenAppearsValid ) return nil;
if ( !_parsedExpirationDate )
{
//
// Token is three base64 encoded payloads separated by '.'
// The payload we want is the middle one, which is a JSON dict, with
// 'exp' being the unix seconds timestamp of the expiration date
// Returning nil is appropriate if no 'exp' is findable
//
NSArray *components = [self.token componentsSeparatedByString:@"."];
NSString *payload = components[1];
NSData* payloadJsonData = [[NSData alloc]
initWithBase64EncodedString:payload
options:NSDataBase64DecodingIgnoreUnknownCharacters];
NSError* jsonError = nil;
NSDictionary* payloadJson = [NSJSONSerialization JSONObjectWithData:payloadJsonData options:0 error:&jsonError];
if ( payloadJson )
{
if ( payloadJson[@"exp"] )
{
NSTimeInterval timestampSeconds = [payloadJson[@"exp"] doubleValue];
_expirationDate = [NSDate dateWithTimeIntervalSince1970:timestampSeconds];
}
}
_parsedExpirationDate = YES;
}
return _expirationDate;
}
问题很简单。当由 NSData -initWithBase64EncodedString 解析时,中间的 base64 blob 是nil
- 这很糟糕。
我检查了base64 blob,它似乎是有效的。我的服务器目前正在返回虚拟数据,所以这里有一个示例 blob:
eyJlbWFpbCI6ImZvb0BiYXIuYmF6IiwiYWNjb3VudElkIjoiMTIzNDUtNjc4OTAtYmFyLWJheiIsImV4cCI6MTM5MDkxNTAzNywiaWF0IjoxMzkwOTE0MTM3fQ
它解码为:
{"email":"foo@bar.baz","accountId":"12345-67890-bar-baz","exp":1390915037,"iat":1390914137}
我在这里测试过:http ://www.base64decode.org
我在我的应用程序的其他地方成功地使用了 NSData 的 base64 方法 - 我认为我在这里没有做任何特别糟糕的事情。但我全是耳朵!有任何想法吗?