美文网首页iOS开发
客户端并发网络请求中Token失效处理方案

客户端并发网络请求中Token失效处理方案

作者: 蚂蚁牙齿不黑 | 来源:发表于2018-04-11 16:09 被阅读12次
    image.png

    近期在做sdk底层网络模块封装的时候碰到一个关于客户端身份认证的问题,拿出来分享一下,可以确定的是我的解决办法并不是最优方案。

    1.什么是Token 机制?

    token的意思是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。 当用户第一次登录后,服务器生成一个Token并将此Token返回给客户端,在以后的请求过程中,需要将该Token作为参数或者放在header里面发送给服务器作为身份验证的一个步骤,无需再次带上用户名和密码,但是服务端每隔一段时间(比如30分钟)就会重新生成Token,这时候客户端再用本地缓存的旧Token去请求就无法通过身份认证,一般状态码都会是401。

    下面这段字符串就是一个完整的Token

    Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSIsImtpZCI6ImEzck1VZ01Gdjl0UGNsTGE2eUYzekFrZnF1RSJ9.eyJpc3MiOiJodHRwczovL29wZW4uaml1emhhbmcubmV0IiwiYXVkIjoiaHR0cHM6Ly9vcGVuLmppdXpoYW5nLm5ldC9yZXNvdXJjZXMiLCJleHAiOjE1MjM0MzMyMTcsIm5iZiI6MTUyMzQyOTYxNywiY2xpZW50X2lkIjoicm8uY2xpZW50Iiwic2NvcGUiOlsib2ZmbGluZV9hY2Nlc3MiLCJyZWFkIiwid3JpdGUiXSwic3ViIjoianpkZXZAanpkZXYiLCJhdXRoX3RpbWUiOiIxNTIzNDI5NTgwIiwiaWRwIjoiaWRzcnYiLCJhbXIiOlsicGFzc3dvcmQiXX0.fxTyygfF9rXTYm4tbkLucoF5tm0Zs7O2i_E-2NfOl1x_iy7J_sg-lYxk7UQDoCTHiOJKKAV3cQ3jAymHnzmXrgcdtJQFaYE1qGjVSf3qdELIum2kyoOAkfJ_FHOtpgNxhSNgIdWA42_lKl1QPCBoxQOQyQsqB2cKXVLkC2J-4w7Cysf8cjo4PfSgWYoB64-NrMx1WdD4R0Q0nZ_1-2Ky7sB7495NoOBf7IJ6J-IP12FCOjk6e404rH2ZKNlURjDs9dURuP1k_9x3eOsW0C3sdewMAxpmUzhw278FgZcG30v-UuHaWv0DnGP3Y9jg5ob2ktAqGg8gqF0m0-It6bSz7Q
    

    2.解决办法

    image.png

    请求A在得知当前缓存的Token失效后就会重新获取服务端的新Token,然后再继续请求A之后的操作

    以objective-c代码描述业务逻辑,会用到部分伪代码

    //  401代表用户身份认证失败
    if(statusCode == 401)
    {
           [HttpTool requestWihtUrlString:URL_GetToken params:params success:^(id response, NSUInteger totalCount) {
             // 1.缓存Token
           [[NSUserDefaults standardUserDefaults] setObject:[dataDic objectForKey:@"access_token"] forKey:@"access_token"];
     
          // 2.重点也就在这里了,iOS中AFN帮你拼接的每一个请求实例NSURLSessionDataTask请求过一次便不再可用   所以我们只能从这个实体类中拿到我们的请求信息重新生成一个datatTask重新请求即可,以AFN发起请求为例,GET 请求最简单,只需要把请求的服务器路径取出来就可以了,而POST,PUT,DELETE等需要从请求题body中把二进制转化为我们想要的参数
                NSMutableDictionary *paramDict = [NSMutableDictionary dictionary];
                NSString *urlStr = task.originalRequest.URL.absoluteString;
                NSString *httpMethod = task.originalRequest.HTTPMethod;
                if (![httpMethod isEqualToString:@"GET"])
                {
                    NSStringEncoding encoding = [HttpTool sharedManager].requestSerializer.stringEncoding;
                    NSData *httpBody = task.originalRequest.HTTPBody;
                    NSString *paramStr = [[[NSString alloc] initWithData:httpBody encoding:encoding] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
                    NSArray *keyValues = [paramStr componentsSeparatedByString:@"&"];
                    for (NSString *keyValue in keyValues)
                    {
                        NSArray *param = [keyValue componentsSeparatedByString:@"="];
                        NSString *key = param.firstObject;
                        NSString *value = param.lastObject;
                        [paramDict setObject:value forKey:key];
                    }
                }
                [HttpTool commonRequestWithUrlString:urlStr
                                          method:httpMethod
                                          params:paramDict
                                         success:successBlock
                                         failure:failureBlock];
    }
    
    

    相关文章

      网友评论

      本文标题:客户端并发网络请求中Token失效处理方案

      本文链接:https://www.haomeiwen.com/subject/ratzhftx.html