2015-10-03 4 views
0

Хотя 401 Unauthorized может показаться им шикарным («Токен доступа отсутствует или недействителен»), он может выдать много HTTP-стека клиента, чтобы вызвать пользователя для учетных данных, что-то не получится в любом случае поскольку обычные механизмы проверки подлинности HTTP не воспроизводятся.401 Статус, возвращенный при ошибках токена доступа

Хотя я могу объединить это, используя другую клиентскую библиотеку, на которую я могу направить, чтобы не пытаться авто-auth или пользовательский запрос (и сделал это), это, по-видимому, нарушает RFC 7235, насколько я могу судить.

Я подозреваю, что 403 Forbidden будет более уступчивым и менее печальным для пользователей API. Большинство из них, вероятно, просто видят какой-либо статус не-2XX и сразу же запускают поиск тела ответа «ошибка» JSON.

У меня есть обход, поэтому я не жалуюсь, но здесь что-то кажется подозрительным. Неужели я чего-то не хватает? Является ли распространенной практикой сейчас использовать 401 таким образом для HTTP-API, подобный REST?

Подробнее

Это работает до тех пор, как используется соответствующий маркер аутентификации, но вызывает GUI подсказку для пользователя/PW, если плохой маркер используется:

Set JsonBag = PBConfig.CloneItem("CreatePushJson") 'Make a deep copy of template JSON. 
With JsonBag 
    .Item("title") = txtTitle.Text 
    .Item("body") = txtBody.Text 
End With 

With XMLHTTP 
    .abort 'Clean up previously failed request if any. 
    .open "POST", PBConfig.Item("CreatePushUrl"), True 
    .setRequestHeader "Access-Token", PBConfig.Item("AccessToken") 
    .setRequestHeader "Content-Type", "application/json" 
    .onreadystatechange = SinkRSChange 
    .send JsonBag.JSON 
End With 

Если подсказка аннулируется пользователем, тогда код 401 получает код.

В свете нижеприведенной информации я попытался отправить токен аутентификации в качестве значения идентификатора пользователя. Однако это вызывает подсказка, даже если токен аутентификации является правильным:

Set JsonBag = PBConfig.CloneItem("CreatePushJson") 'Make a deep copy of template JSON. 
With JsonBag 
    .Item("title") = txtTitle.Text 
    .Item("body") = txtBody.Text 
End With 

With XMLHTTP 
    .abort 'Clean up previously failed request if any. 
    .open "POST", PBConfig.Item("CreatePushUrl"), True, PBConfig.Item("AccessToken") 
    .setRequestHeader "Content-Type", "application/json" 
    .onreadystatechange = SinkRSChange 
    .send JsonBag.JSON 
End With 

Если пользователь вручную вводит действительный маркер аутентификации в строку в качестве идентификатора пользователя запрос затем преуспевает.

на основе новой информации ниже

Это может быть сделано, чтобы работать на Явно отправив "." в качестве пароля:

Set JsonBag = PBConfig.CloneItem("CreatePushJson") 'Make a deep copy of template JSON. 
With JsonBag 
    .Item("title") = txtTitle.Text 
    .Item("body") = txtBody.Text 
End With 

With XMLHTTP 
    .abort 'Clean up previously failed request if any. 
    .open "POST", PBConfig.Item("CreatePushUrl"), True, PBConfig.Item("AccessToken"), "." 
    .setRequestHeader "Content-Type", "application/json" 
    .onreadystatechange = SinkRSChange 
    .send JsonBag.JSON 
End With 

правильное значение работ лексем, плохой лексем значение возвращает 401, где он может обрабатываться. Теперь учетные данные не запрашивают диалоговые окна.

ответ

0

Стандартные механизмы аутентификации HTTP технически находятся в игре. Api даже запрашивает у вашего браузера учетные данные, чтобы вы могли делать запросы в своем браузере (кто-то действительно запросил это).

HTTP-библиотеки, которые имеют особое поведение для 401, действительно представляют собой проблему, но однажды это случилось, мне удалось отключить обработку магии 401. Я понятия не имею, кто нарушает RFC 7235. RFC 2616 10.4.2, по-видимому, указывает на то, что текущее поведение является «правильным». У вас есть список HTTP-клиентов, которые запрашивают у пользователя учетные данные?

Возможно, здесь больше смысла, но Stripe по крайней мере использует 401: https://stripe.com/docs/api#errors, и все они относятся к REST. Переход на 403 также сломал бы всех существующих клиентов. Большинство клиентов на самом деле не смотрят на тело JSON как ни странно, они просто смотрят на код состояния.

Я думаю, что если я сделаю еще один HTTP API, он будет иметь только коды статуса 200/400/500 с POST из закодированных JSON тел и ответы JSON.

+0

Если используется обычный HTTP Auth, то 401 имеет смысл. Возможно, я неправильно понял документы API Pushbullet, но они, похоже, исключают это и вместо этого требуют заголовок «Access-Token». Поэтому, когда отправляется плохой токен, 401 действительно работает, если ваша библиотека не сообщит об этом вам и вместо этого начнет запрашивать пользователя для пользователя/pw входа в систему. Стек Microsoft UrlMon (под IE, библиотека MSXML и т. Д.) Будет делать это, хотя их стек WinHttp этого не делает. Кажется маловероятным, что большинство браузеров тоже этого не сделают. Это просто ловушка, ожидающая некоторых пользователей API. – Bob77

+0

Глядя на мои журналы и RFC, я подозреваю, что статус «401» не является проблемой, так как возвращается заголовок «Www-Authenticate». Если этот клиент не использовал анонимные HTTP-учетные данные в 1-м месте, он, вероятно, получил бы «401» вместо того, чтобы «управлять» с помощью подсказки. – Bob77

+0

Ах, последний пункт, который я только что сделал, неправильно тоже. Даже отправка правильного токена аутентификации, поскольку идентификатор пользователя получает сообщение 401 и GUI. См. Правки в оригинальное сообщение выше. – Bob77

0

Альтернатива:

Если поддержка нижнего уровня версий Windows, не требуется вы можете использовать WinHttp.WinHttpRequest объект в качестве замены для объекта Msxml2.XMLHTTP, используемого в примерах выше вопрос.

Set JsonBag = PBConfig.CloneItem("CreatePushJson") 'Make a copy. 
JsonBag("title") = txtTitle.Text 
JsonBag("body") = txtBody.Text 

With WinHttp 
    .Abort 'Clean up previously failed request if any. 
    .Open "POST", PBConfig("CreatePushUrl"), True 
    .SetAutoLogonPolicy AutoLogonPolicy_Never 
    .SetRequestHeader "Access-Token", PBConfig("AccessToken") 
    .SetRequestHeader "Content-Type", "application/json" 
    .Send JsonBag.JSON 
End With 

Ключом к этому является .SetAutoLogonPolicy AutoLogonPolicy_Never, который мы не располагаем со старшим классом.

Обратите внимание, что в этом примере используется тот факт, что JsonBag имеет значение .Item() как свое свойство по умолчанию ... на всякий случай вам было интересно узнать об этой разнице в этом фрагменте кода по сравнению с предыдущими. Он не имеет никакого отношения к использованию WinHttp и может быть написан таким же образом в более ранних фрагментах.

Смежные вопросы