javascript - Reactjs 获取身份验证和访问 token ,无法解析响应

标签 javascript reactjs authentication cors fetch-api

我对 ReactJS 还很陌生。

我使用的是 Chrome 浏览器。

我正在尝试使用 ReactJS 创建登录页面。该页面很简单,包含用户 ID 和密码。身份验证发生在我们的 SSO 服务器上,这意味着我必须使用 fetch 调用在服务器上发布数据并获取 access_token 作为响应。

问题如下:

我在控制台中没有得到响应。但是,当我查看开发人员工具上的“网络”选项卡时,我可以看到有一个有效的响应,其中包含所有必填字段,其中包括 access_token 。 现在确定我应该如何解析这个。

这是因为 fetch 是异步调用吗?

这是我的整个页面代码。

P.S:某些代码未格式化。

import React, {Component} from 'react';
import '../App/App.css';
import {FormGroup, FormControl, InputGroup} from 'react-bootstrap';

class Auth extends Component {


    constructor(props) {
        super(props);
        this.state = {
            userid: '',
            password: '',
            accessToken: ''
        }
    }

    submit() {
        console.log('state', this.state);
        const BASE_URL = 'MY SSO URL';
        const params = {
            'grant_type': 'password',
            'username': this.state.userid,
            'password': this.state.password,
            'client_secret': 'secred',
            'client_id': 'client_id',
        };
        const formData = new FormData();
        for (let p in params) {
            formData.append(p, params[p]);
        }
        const headers = {
            'Access-Control-Allow-Origin': '*'
        };
        const request = {
            method: 'POST',
            headers: headers,
            body: formData,
            mode: 'no-cors'
        };

        fetch(BASE_URL, request)
            .then((response) => response.text())
            .then((responseText) => {
                console.log('text',responseText);
            })
            .catch((error) => {
                console.warn(error);
            });
        console.log('all done');
    }

    render() {
        return (
            <div className="login">
                <div className="legend">Signin</div>
                <FormGroup>
                    <InputGroup>
                        <div className="input">
                            <FormControl
                                type="text"
                                placeholder="Enter User Id or email"
                                onChange={event => this.setState({userid: event.target.value})}
                                onKeyPress={
                                    event => {
                                        if (event.key === 'Enter') {
                                            this.submit()
                                        }
                                    }}
                            />
                        </div>
                        <div className="input">
                            <FormControl
                                type="password"
                                placeholder="enter password"
                                onChange={event => {
                                    console.log(event.target.value)
                                    this.setState({password: event.target.value})
                                }}
                                onKeyPress={
                                    event => {
                                        if (event.key === 'Enter') {
                                            this.submit()
                                        }
                                    }}
                            />
                        </div>
                        <FormControl
                            type="submit"
                            onClick={() => this.submit()}
                        />
                    </InputGroup>
                </FormGroup>
            </div>
        )
    }
}
export default Auth;

我尝试了response.json(),这给出了错误:输入意外结束

最佳答案

到目前为止,您的 fetch(…) 请求的前端 JavaScript 代码是:

mode: 'no-cors'

删除它。这就是您的代码无法访问响应的确切原因。

你永远、永远不想做 mode: "no-cors" 。唯一实际做的就是告诉浏览器,永远不要让我的前端 JavaScript 代码访问此请求的响应

const headers = {
    'Access-Control-Allow-Origin': '*'
};

也删除这些行。 Access-Control-Allow-Origin 是响应 header 。您永远不想在请求中发送它。唯一的效果是触发浏览器进行预检。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests

我猜测您尝试 mode: 'no-cors' 并在请求中发送 Access-Control-Allow-Origin 的原因是您之前尝试过没有这些的请求,并且您在浏览器控制台中收到一条错误消息,指出响应缺少 Access-Control-Allow-Origin

如果是这样,您无法通过更改前端 JavaScript 代码来解决这个问题,除非更改代码以通过代理发出请求,如 "No 'Access-Control-Allow-Origin' header is present on the requested resource" 处的答案中所述。

要么您需要获取 BASE_URL 地址的服务器所有者,以将服务器配置为在其响应中发送 Access-Control-Allow-Origin


这里有一个更长的解释:

当您发出请求的服务器明确表明他们选择接收跨源请求(通过发送 Access-Control-Allow-Origin 来执行此操作)时,您的浏览器只会让您的前端 JavaScript 代码访问来自跨源请求的响应他们的响应中的响应 header 。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS 有更多详细信息。

浏览器是唯一对跨源请求实现限制的客户端,并且它们仅在 Web 应用程序上实现这些限制。

这就是为什么即使您看到请求的资源上也不存在“Access-Control-Allow-Origin” header 。因此,您的开发工具控制台中不允许访问 Origin ... 消息,您仍然可以转到开发工具中的“网络”选项卡并在那里查看响应。

这是因为服务器已发送响应并且浏览器已收到它,但浏览器只是拒绝允许您的前端 JavaScript 代码访问响应,因为发送响应的服务器尚未选择交叉- 通过发送 Access-Control-Allow-Origin 响应头来发起请求。

当您从curl等发出请求时可以很好地获得响应的原因是,如果缺少Access-Control-Allow-Origin响应 header ,除了浏览器之外的任何客户端都不会拒绝允许您的代码访问响应。但浏览器总是会的。

请注意,服务器不会执行任何阻止或拒绝响应任何请求的操作。服务器始终继续只接收请求并发送响应。唯一的区别在于服务器是否在响应中发送 Access-Control-Allow-Origin header 。

关于javascript - Reactjs 获取身份验证和访问 token ,无法解析响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43880623/

相关文章:

javascript - 如何访问父 Controller 中指令的对象?

javascript - 从对象 ES6 创建键值数组

javascript - 提交无按钮表单时如何触发函数

javascript - float 和偏移 Javascript 值

reactjs - “react-scripts”不被识别为内部或外部命令、可操作程序或批处理文件

php - Symfony2 创建经过身份验证的 session

css - ReactStrap 输入组错误(不是 100% 宽度)

reactjs - 处理获取的数据 - RTK Query/Redux 工具包/React

angularjs - 使用 MEAN + Passport 根据用户角色更改 View

iphone - 使用 FBConnect 通过 Facebook 通过 iPhone 应用程序对用户进行身份验证的 Rails 后端服务器进行身份验证