出现HTTP: 401 的时候的解析思路

说在前面的话:

最近工作确实比较忙了一些, 毕竟是年初,很多事情都需要重新布置, 一年之计在于春嘛;
这几天,新来了一些小伙伴, 在他们接下来的一些工作中, 也发现了一些比较有意思的bug, 有些bug确属不应该,不过也有些bug比较有意思, 有时间了,我会慢慢的整理一些发上来和大家分享, 今天先分享一个: HTTP: 401

介绍: 什么是HTTP: 401

时常做应用开发的伙伴们,估计大家对这个数字并不陌生, 毕竟只要你的应用需要申请服务器数据, 那么难免会遇到它, 当然我的新来的这批小伙伴们也比较幸运的遇到了它, 嗯, 确实比较幸运, 因为bug出现,就是学习和进步的时候到了!
所以,我也就花了一些空余时间来为大家整理了一下;

常见的HTTP:401错误码:

401.1 - Logon failed. -登陆失败
401.2 - Logon failed due to server configuration.-基于服务器配置的登陆失败
401.3 - Unauthorized due to ACL on resource.-资源访问控制列表返回未授权
401.4 - Authorization failed by filter.-服务器filter返回未授权
401.5 - Authorization failed by ISAPI/CGI application.-服务器ISAPI/CGI返回未授权

对于401,我们可以用一句话描述它:那就是 HTTP 401 错误 - 未授权: (Unauthorized) [绝大多数情况下]

简单的来说: 就是你的Web服务器认为,客户端发送的 HTTP 数据流是正确的,但进入网址 (URL) 资源 , 需要用户身份验证 , 而相关信息 尚未被提供, 或 已提供但没有通过授权测试。
这就是通常所知的“ HTTP 基本验证 ”。
而需客户端提供的验证请求在 HTTP 协议中被定义为 WWW – 验证标头字段 (WWW-Authenticate header field) 。

那这个401错误码 什么时候会产生呢?

HTTP 循环中的 401错误

任何客户端 ( 比如浏览器,比如APP等等 ) ,都需要通过以下循环去向服务器请求数据:

1.首先从你的站点的 IP 名称 ( 即您站点的网址-URL, 不带起始的 ‘http://') 获得一个 IP 地址。这是由DNS来解析的;
2.接着, 打开一个 IP 套接字 (socket) 连接到该 IP 地址。
3.通过该套接字写 HTTP 数据流。
4.从您的Web服务器接受响应的 HTTP 数据流。该数据流包括状态编码, 其值取决于 HTTP 协议 。 解析该数据流得到 状态编码和其他有用信息。

而401错误在容易在以上所述的最后一步产生,即当客户端收到 HTTP 状态编码并识别其为 ‘401‘ 时

例如我这里做了一个测试: 大家看代码 ,(由于请求网络服务器比较不好操作,所以,这个测试我用了自己电脑搭建的本地服务器;)
首先我给自己电脑的本地服务器(webDav)发送一个put请求, 准备上传一张图片到webDav服务器

NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/uploads/123.jpg"]; 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];    
request.HTTPMethod =@"put";

然后获取一张本地的图片,

 //本地文件    
NSURL *fileUrl = [[NSBundle mainBundle] URLForResource:@"head2.png"withExtension:nil];  
[[[NSURLSession sharedSession] uploadTaskWithRequest:request fromFile:
   fileUrl completionHandler:^(NSData *_Nullabledata, NSURLResponse *_Nullableresponse, NSError *_Nullableerror) {
        NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];    
}] resume];

接着开始执行:

这里就会出现问题:
输出结果:

输出结果

通过输出结果,可以明显的看得到 服务器返回的是401, 因为我们没有授权, 那么怎样授权呢?

解决 401 错误 – 情景一 : 有防御性的安全策略

通常情况下
每个Web服务器都有自己的方式管理用户验证。通常由该网站的网络安全员(例如,系统管理员)决定哪些用户被允许访问该网址。 该人员使用 Web 服务器软件来建立这些用户的用户名及其密码。 因此, 如果您需要访问某个网址(或您忘记了自己的用户名和密码), 只有该网站的网络安全员可以帮助您。任何安全问题需直接提交给他们。

如果你认为该网站上的网页 应该 是对任何互联网用户开放的, 那么 401 信息就表明了一个更深层问题。 首先,您可以通过一个浏览器检查您的网址。 该浏览器应该运行在一台您以前从未使用过, 也不包含任何有关您的信息的计算机上, 同时, 您还应避免使用您以前用过的身份验证(密码等)。 理想情况是, 这一切应该通过一个完全不同于任何您用过的互联网连接(例如由不同的互联网服务供应商- ISP 提供的拨号连接)。 简而言之,您要模拟一个完全陌生的人通过网上冲浪访问您的网页的情况。

如果这种通过浏览器的检查表明没有授权问题,则可能是您的 Web 服务器 ( 或周边系统 ) 被设置为不允许某种 HTTP 传输模式。 换句话说就是, 来自一个知名浏览器的 HTTP 通讯是允许的, 但来自其他系统的自动通讯则被拒绝, 并生成 401 错误代码。这是一种异常情况, 但是也许表明您的 Web 服务器周围 采取了非常具有防御性的安全策略。

比如: iOS9.0之后,就统一规定,对于http请求,只有经过苹果认可的证书且是https:// 的,才可以直接通过访问,如果还是http:// 或者,不是苹果认可的证书的https,都是不可以直接访问的, 所以,通常情况下,解决这类问题,我们会事先在info.plist文件中做一些配置, 也就是我们常说的ATS配置: 我们可以把下面这几行配置添加到info.plist文件中, 首先用源代码方式打开info.plist文件, 然后拷贝下面的几行代码: 如下:

  <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>

解决 401 错误 – 情景二: 密码,账户名错误

情景二: 需要提供密码和账号
当服务器需要验证您的帐户时,您可以有选择性地提供两项信息

  1. 网站用户名,
  2. 网站密码。
    当然只有当您的站点使用 HTTP 基本验证时您才应该提供这些信息。 如果您不提供这些信息,服务器是通不过的,您也会得到 401 错误。

就如最上面的put请求的代码, 在服务器端,其实我是设定了需要密码和账号才能通过的,
所以,这种情况下,我们就需要提供账号和密码给服务器了,
当然,实际开发中,密码和账号是需要严格加密的,都是需要和服务器人员沟通一套非常保密的加密的方法的, 整个过程是比较复杂的,
不过由于我这里只是做一个演示, 那么就不需要特别复杂了, 就简单一点,说明一个思路即可:
这里,我就手动来拼接一个账号和密码, 密码加密就用最简单的base64编码;

假设我们的账号是admin,密码也是123456, 那么我们怎样来设定密码呢?
首先我们需要定义方法,来拼接密码,并转化为base64编码;

//定义一个方法: 获取授权的字符串
- (NSString *)getAuth:(NSString *)name pwd:(NSString *)pwd {
    //拼字符串  admin:123456
    NSString *tmpStr = [NSString stringWithFormat:@"%@:%@",name,pwd];
    //base64编码
    tmpStr = [self base64Encode:tmpStr];

    return [NSString stringWithFormat:@"Basic %@",tmpStr];
}

//base64编码
- (NSString *)base64Encode:(NSString *)str  {
    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
    return [data base64EncodedStringWithOptions:0];
}

然后我们在发送put请求的时候, 就同时提供授权

//上传文件
- (void)uploadTask {
    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/uploads/123.jpg"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"put";
    //设置账号和密码
    //Authorization: Basic YWRtaW46MTIzNDU2
    // admin:123456
    [request setValue:[self getAuth:@"admin" pwd:@"123456"] forHTTPHeaderField:@"Authorization"];
    
    //本地文件
    NSURL *fileUrl = [[NSBundle mainBundle] URLForResource:@"head2.png" withExtension:nil];  
    [[[NSURLSession sharedSession] uploadTaskWithRequest:request fromFile:fileUrl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        
        NSLog(@"--%@",str);
        
    }] resume];
}

执行结果:

执行结果:

通过结果,我们可以看出, 已经上传成功了, 也就是说,我们顺利的解决了401问题,

总结解决bug的思路:

如果遇到401问题, 我们解决的思路,可以这样来考虑:

  1. 优先考虑是否是需要验证,也就是是否需要授权账号和密码信息;
  2. 如果是开放的服务器资源, 需要考虑的是是否有防御性的安全策略;

一般情况下,都属于这两种原因,

以上属于我整理的,如有不足之处,望大家斧正! 感谢!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • 一、概念(载录于:http://www.cnblogs.com/EricaMIN1987_IT/p/3837436...
    yuantao123434阅读 8,328评论 6 152
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • Http协议详解 标签(空格分隔): Linux 声明:本片文章非原创,内容来源于博客园作者MIN飞翔的HTTP协...
    Sivin阅读 5,201评论 3 82
  • 前言:最近发现自己在网络相关这一块基础很是欠缺,所以准备花时间了解一下,本文主要是讲http协议的一些基础,和一些...
    justCode_阅读 2,092评论 0 23
  • 工作流程 一次HTTP操作称为一个事务,其工作过程可分为四步: 1)首先客户机与服务器需要建立连接。只要单击某个超...
    保川阅读 4,581评论 2 14