首页 > 解决方案 > Aurelia HttpClient.Fetch 从 Auth0 获取令牌,但在 Postman 中工作正常

问题描述

使用 Postman 时,我可以毫不费力地返回不记名令牌。但是,在使用 Aurelia 时,我收到状态 200,唯一的响应是“OK”。我看到请求方法仍然是“选项”。我在 Chrome 控制台中看到了这一点:

Failed to load https://------.auth0.com/oauth/token: Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.

但是,从我可以看到响应中显示的标题以及我所看到的一切看起来都在那里。

这是我从邮递员那里收到的信息:

Response: Status 200 OK
JSON:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGci...{shortened for brevity}",
"expires_in": 86400,
"token_type": "Bearer"
}

这是来自 Aurelia 的代码:

private getToken() {
    var postData = { "client_id": API_CONFIG.clientId, "client_secret": API_CONFIG.clientSecret, "audience": API_CONFIG.audience, "grant_type": "client_credentials" };
    this.http.fetch('https://kimberlite.auth0.com/oauth/token', {
        credentials: 'omit',
        headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': 'http://localhost:3000/'
        },
        mode: 'cors',
        method: 'post',
        body: JSON.stringify(postData)
    }).then(result => result.json())
        .then(data => {
            localStorage.setItem('api_access_token', data.access_token);
            localStorage.setItem('api_expires_at', new Date().getTime() + data.expires_in);
        });
}

在此处输入图像描述 在此处输入图像描述

我已经搜索过,但没有找到任何可以帮助我通过这个的东西。我错过了什么?非常感谢任何帮助

在阅读了下面 Jesse 的评论后,我删除了“Access-Control-Allow-Origin”的标题并收到相同的 200 OK。但是,在 Google Chrome 中收到错误Origin 'localhost:3000'; is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."

阅读其他问题后,我尝试删除所有标题并收到401 Unathorized并带有以下响应{{"error":"access_denied","error_description":"Unauthorized"}

    private getToken() {
    var postData = { "client_id": API_CONFIG.clientId, "client_secret": API_CONFIG.clientSecret, "audience": API_CONFIG.audience, "grant_type": "client_credentials" };
    let http = new HttpClient();
    http.fetch('https://kimberlite.auth0.com/oauth/token', {
        credentials: 'omit',
        //headers: {
        //    'Content-Type': 'application/json'
        //},
        mode: 'cors',
        method: 'post',
        body: JSON.stringify(postData)
    }).then(result => result.json())
        .then(data => {
            localStorage.setItem('api_access_token', data.access_token);
            localStorage.setItem('api_expires_at', new Date().getTime() + data.expires_in);
        });
}

好的,我刚刚在 Firefox 中尝试过,仅使用“Content-Type”标头并收到了预期的响应。我需要注意 Chrome(大多数用户将要使用的)的某些内容吗? 在此处输入图像描述

标签: aureliaauth0

解决方案


您不应该access-control-allow-origin在请求上设置标头。在 CORS 请求中,服务器端点需要在 OPTIONS 请求的响应中设置此标头。


跨域资源共享的工作方式是客户端首先对服务器端点进行 OPTIONS 调用。服务器端点应配置为使用 CORS,并具有允许的来源列表(或简单*地允许所有来源)。然后在响应此 OPTIONS 请求时,服务器将设置Access-Control-Allow-Origin: https://localhost:3000以指示允许源发出请求。您也可以在回复中看到这一点:

响应头

然后客户端继续对同一端点进行 GET 或 POST 调用,并实际检索/存储数据。

在您的情况下,如果您使用 Aurelia fetch 客户端发出请求,则不需要设置标头来执行此操作。您可以简单地执行以下操作:

private getToken() {
    var postData = { "client_id": API_CONFIG.clientId, "client_secret": API_CONFIG.clientSecret, "audience": API_CONFIG.audience, "grant_type": "client_credentials" };
    this.http.fetch('https://kimberlite.auth0.com/oauth/token', {
        credentials: 'omit',
        headers: {
            'Content-Type': 'application/json'
        },
        mode: 'cors',
        method: 'post',
        body: JSON.stringify(postData)
    }).then(result => result.json())
        .then(data => {
            localStorage.setItem('api_access_token', data.access_token);
            localStorage.setItem('api_expires_at', new Date().getTime() + data.expires_in);
        });
}

推荐阅读