401 Unauthorized on unprotected resource
401 Unauthorized on unprotected resource
我的设置
我有一个带有 REST API 的服务器,它在带有 API 平台的 Symfony 上运行。对我的资源的 GET 请求不需要授权,但其他操作需要授权。使用 JWT Bearer 令牌处理授权。
客户端使用 React-admin 和 API 平台管理员。我添加了这段代码来发送 JWT 令牌以及操作:
// dataProvider.js
import React from "react";
import { hydraDataProvider, fetchHydra as baseFetchHydra } from "@api-platform/admin";
export default entrypoint => {
const fetchHeaders = { Authorization: `Bearer ${localStorage.getItem("token")}` };
const fetchHydra = (url, options = {}) => baseFetchHydra(url, {
...options,
headers: new Headers(fetchHeaders),
});
return hydraDataProvider(entrypoint, fetchHydra);
};
问题
当我现在登录我的管理界面时,我得到了一个 401 Unauthorized
响应,因为服务器不期望 GET 请求的令牌。
请求Headers:
Host: localhost:8000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0
Accept: application/ld+json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://localhost:3000/
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1ODQ2NzcwMTYsImV4cCI6MTU4NDY4MDYxNiwicm9sZXMiOlsiUk9MRV9BRE1JTiJdLCJ1c2VybmFtZSI6IlNvbWVib2R5In0.O_StagfEJy5VQS-5s-DjuwzOlUgrl3MTmxPfZUU0J1go06tKOpLjiBrEIJpjo5AK67w93SfsUaIBop8apoacHQ
Content-Type: application/ld+json
Origin: http://localhost:3000
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
TE: Trailers
回复Headers:
HTTP/2 401 Unauthorized
access-control-allow-origin: http://localhost:3000
access-control-expose-headers: link
cache-control: no-cache, private
content-type: application/json
date: Fri, 20 Mar 2020 04:40:39 GMT
link: <https://localhost:8000/api/docs.jsonld>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation"
www-authenticate: Bearer
x-debug-token: 720652
x-debug-token-link: https://localhost:8000/_profiler/720652
x-powered-by: PHP/7.4.1
x-robots-tag: noindex
content-length: 282
X-Firefox-Spdy: h2
当我在浏览器中从请求 headers 中手动删除授权行并重试时,它起作用了。
我的问题:
- 这是预期的行为吗?
- 客户端是否应该总是发送令牌?
- 如果应该始终发送令牌,我该如何告诉 API 平台接受它,即使不需要它?
- 如果只应在需要时发送令牌,我如何让 hydraDataProvider 知道?
经过许多小时尝试不同的解决方案,我终于解决了这个问题。
我的问题的答案
- 不,发送有效令牌不应导致 401 响应。
- 可以在每次请求时发送令牌。
我的解决方案
问题是我的服务器上的 JWT 身份验证配置不正确。 None 我遵循的指南实际上涵盖了以下情况:
我将用户电子邮件作为标识符,而不是用户名。
所以最终发生的是令牌包含编码的用户名,在我的例子中这不是唯一标识符。要告诉 JWT 使用电子邮件,我必须将 user_identity_field 设置为 email.
// config/packages/lexik_jwt_authentication.yaml
lexik_jwt_authentication:
secret_key: '%env(resolve:JWT_SECRET_KEY)%'
public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
user_identity_field: email
我的设置
我有一个带有 REST API 的服务器,它在带有 API 平台的 Symfony 上运行。对我的资源的 GET 请求不需要授权,但其他操作需要授权。使用 JWT Bearer 令牌处理授权。
客户端使用 React-admin 和 API 平台管理员。我添加了这段代码来发送 JWT 令牌以及操作:
// dataProvider.js
import React from "react";
import { hydraDataProvider, fetchHydra as baseFetchHydra } from "@api-platform/admin";
export default entrypoint => {
const fetchHeaders = { Authorization: `Bearer ${localStorage.getItem("token")}` };
const fetchHydra = (url, options = {}) => baseFetchHydra(url, {
...options,
headers: new Headers(fetchHeaders),
});
return hydraDataProvider(entrypoint, fetchHydra);
};
问题
当我现在登录我的管理界面时,我得到了一个 401 Unauthorized
响应,因为服务器不期望 GET 请求的令牌。
请求Headers:
Host: localhost:8000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0
Accept: application/ld+json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://localhost:3000/
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1ODQ2NzcwMTYsImV4cCI6MTU4NDY4MDYxNiwicm9sZXMiOlsiUk9MRV9BRE1JTiJdLCJ1c2VybmFtZSI6IlNvbWVib2R5In0.O_StagfEJy5VQS-5s-DjuwzOlUgrl3MTmxPfZUU0J1go06tKOpLjiBrEIJpjo5AK67w93SfsUaIBop8apoacHQ
Content-Type: application/ld+json
Origin: http://localhost:3000
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
TE: Trailers
回复Headers:
HTTP/2 401 Unauthorized
access-control-allow-origin: http://localhost:3000
access-control-expose-headers: link
cache-control: no-cache, private
content-type: application/json
date: Fri, 20 Mar 2020 04:40:39 GMT
link: <https://localhost:8000/api/docs.jsonld>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation"
www-authenticate: Bearer
x-debug-token: 720652
x-debug-token-link: https://localhost:8000/_profiler/720652
x-powered-by: PHP/7.4.1
x-robots-tag: noindex
content-length: 282
X-Firefox-Spdy: h2
当我在浏览器中从请求 headers 中手动删除授权行并重试时,它起作用了。
我的问题:
- 这是预期的行为吗?
- 客户端是否应该总是发送令牌?
- 如果应该始终发送令牌,我该如何告诉 API 平台接受它,即使不需要它?
- 如果只应在需要时发送令牌,我如何让 hydraDataProvider 知道?
经过许多小时尝试不同的解决方案,我终于解决了这个问题。
我的问题的答案
- 不,发送有效令牌不应导致 401 响应。
- 可以在每次请求时发送令牌。
我的解决方案
问题是我的服务器上的 JWT 身份验证配置不正确。 None 我遵循的指南实际上涵盖了以下情况: 我将用户电子邮件作为标识符,而不是用户名。
所以最终发生的是令牌包含编码的用户名,在我的例子中这不是唯一标识符。要告诉 JWT 使用电子邮件,我必须将 user_identity_field 设置为 email.
// config/packages/lexik_jwt_authentication.yaml
lexik_jwt_authentication:
secret_key: '%env(resolve:JWT_SECRET_KEY)%'
public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
user_identity_field: email