NSData 不接受有效的 base64 编码字符串 [英] NSData won't accept valid base64 encoded string

查看:34
本文介绍了NSData 不接受有效的 base64 编码字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 iOS (7) cient 端实现 JSON Web Token 身份验证.它运作良好.我的应用接收令牌,并可以使用它们对我的服务器进行经过身份验证的调用.

I'm implementing JSON Web Token authentication on the iOS (7) cient-side. It's working nicely. My app rceives tokens, and can make authenticated calls to my server with them.

现在,我希望我的客户端代码检查令牌的到期日期,以便知道何时重新进行身份验证.检查 JWT 身份验证令牌的到期日期很简单.授权令牌是 3 个 base64 编码的 JSON blob,用."分隔.- 过期时间戳位于中间的 blob 中,位于名为 ext 的字段中.自 unix 时代以来已经过了几秒钟.

Now, I want my client side code to check for an expiration date on the token so it can know when to re-authenticate. Checking for the expiration date on a JWT auth token is straightforward. The authorization token is 3 base64 encoded JSON blobs, separated by a '.' - The expiration timestamp is in the middle blob, in a field called ext. It's seconds since unix epoch.

所以我的代码看起来像这样:

So my code's looking like so:

- (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 - 这很糟糕.

The problem is simple. The middle base64 blob, when parsed by NSData -initWithBase64EncodedString is nil - and that's bad.

我检查了 base64 blob,它似乎是有效的.我的服务器目前正在返回虚拟数据,所以这里有一个示例 blob:eyJlbWFpbCI6ImZvb0BiYXIuYmF6IiwiYWNjb3VudElkIjoiMTIzNDUtNjc4OTAtYmFyLWJheiIsImV4cCI6MTM5MDkxNTAzNywiaWF0IjoxMzkwOTE0MTM3fQ

I've checked the base64 blob and it seems to be valid. My server's returning dummy data for the moment so here's an example blob: eyJlbWFpbCI6ImZvb0BiYXIuYmF6IiwiYWNjb3VudElkIjoiMTIzNDUtNjc4OTAtYmFyLWJheiIsImV4cCI6MTM5MDkxNTAzNywiaWF0IjoxMzkwOTE0MTM3fQ

解码为:

{"email":"foo@bar.baz","accountId":"12345-67890-bar-baz","exp":1390915037,"iat":1390914137}

我在这里测试过:http://www.base64decode.org

我在我的应用程序的其他地方成功地使用了 NSData 的 base64 方法 - 我认为我在这里没有做任何特别糟糕的事情.但我全是耳朵!有什么想法吗?

I've used NSData's base64 methods elswhere in my app with success - I don't think I'm doing anything particularly broken here. But I'm all ears! Any ideas?

推荐答案

您的 Base64 字符串无效.它必须用 = 字符填充长度是 4 的倍数.在您的情况下:"eyJlbWFp....MTM3fQ==".

Your Base64 string is not valid. It must be padded with = characters to have a length that is a multiple of 4. In your case: "eyJlbWFp....MTM3fQ==".

使用此填充,initWithBase64EncodedString 可以正确解码 Base64 字符串.

With this padding, initWithBase64EncodedString decodes the Base64 string correctly.

这篇关于NSData 不接受有效的 base64 编码字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆