React JS - 如何通过 fetch 语句验证凭据

Posted

技术标签:

【中文标题】React JS - 如何通过 fetch 语句验证凭据【英文标题】:React JS - How to authenticate credentials via a fetch statement 【发布时间】:2018-10-20 21:23:15 【问题描述】:

我的目标是创建一个运行 json Rest 服务的 React JS 登录页面。在 Postman 中,当我输入服务的 URL 时,将其设置为以 POST 方式运行,并将以下 JSON 输入到正文中: 用户名:“我的用户名”,密码:“我的密码” ...返回一个令牌。所以在我的 fetch 子句中,我使用 JSON.stringify 将用户名和密码传递给服务器。

我是使用 Fetch 和 react 的新手,所以我的问题是,我如何开始验证各种用户,仅使用 react JS 和 fetch?我假设,我要在 Fetch 子句的第二个 then 内编写我的逻辑?

目前,我的页面接受任何凭据,并在单击提交按钮后将用户路由到登录页面。我有一个包含 fetch 的函数,现在在单击 onSubmit 按钮后调用 fetch 函数,该按钮现在获取令牌。

这是我的代码:

import React,  Component  from 'react';
import ReactDOM from 'react-dom';
import './Login.css';
import  withRouter  from 'react-router-dom';

class Login extends Component 

    constructor() 
        super();
        this.state = 
            data: [],
            username: "",
            password: "",
            token: "",
        ;
     //end constructor

    componentWillMount() 
    

    componentDidMount() 
        this.fetchData();
    

    fetchData() 
        fetch('http://theapi/api/auth', 
            method: 'POST',
            headers: 
                'Content-type': 'application/json',
            ,
             body: JSON.stringify(
                username: 'myUserName',
                password: 'myPassword',
                Authorization: 'TheReturnedToken',
            )
        ) /*end fetch */
        .then(results => results.json())
        .then(data => this.setState( data: data )

        )
    

    //request the token
      requestAccessToken(data) 
        const loginInfo = '$data&grant_type=password';
        return fetch('$API_URLToken', 
          method: 'POST',
          headers: new Headers(
            'Content-Type': 'application/json',
          ),
          body: loginInfo,
        )
          .then((response) => response.json());
      

      //authenticate request
      requestUserInfo(token) 
        return fetch('$API_URLapi/participant/userinfo', 
          method: 'GET',
          headers: new Headers(
            Authorization: 'Bearer $token',
          ),
        )
          .then((response) => response.json());
      

    change = (e) => 
        this.setState(
            [e.target.name]: e.target.value
        );
    ; //end change

    onSubmit = (e) =>
        this.fetchData();
        e.preventDefault();
        //console.log(this.state);
        this.setState(
             username: "",
             password: "",
            );

        this.props.history.push('/landing');
        ;

    render() 
    console.log(this.state.data);
        return (
           <div>
                <div className="loginContainer">
                <h2>Member Login</h2>
                    <form>
                            <input
                            id="username"
                            name="username"
                            placeholder="User Name"
                            value=this.state.username
                            onChange=e => this.change(e) 
                            className="form-control"
                            />  <br />

                            <input
                            id="password"
                            name="password"
                            type="password"
                            placeholder="Password"
                            value=this.state.password
                            onChange=e => this.change(e) 
                            className="form-control"
                            />  <br />

                        <button onClick=e => this.onSubmit(e) className="btn btn-primary">Submit</button>
                        </form>
                    </div>
            </div>
        );
      


export default withRouter(Login);

如何开始让我的表单对各种用户进行身份验证?基本上,我试图让我的页面接受用户名和密码,如果两者匹配,然后将用户路由到登录页面。

【问题讨论】:

Fetch 不是 React 的概念。我建议在将 UI 引入之前了解如何通过 HTTP 进行通信。 将 componentDidMount 代码移动到 onSubmit 这样当您点击提交按钮时,它将调用 fetch 您应该在数据库中存储散列或加密密码,并让 API 进行密码比较。 React 应用程序应该只关心 API 是否说用户名/密码是好的。 【参考方案1】:

不要将您的授权令牌放在正文中。把它放在页眉中。第一个函数将传入用户名、密码和身份验证类型(即grant_type=password)。然后我的第二个函数将使用它来验证请求。不再需要传递任何用户信息,因为我的 api 根据传入的令牌知道谁在请求。OAuth 2.0 is here 的当前文档,您可以找到有关使用带有 fetch at Mozilla's fetch documentation 的标头的更多信息.

// request the token
// subscribe to this event and use the returned json to save your token to state or session storage
export function requestAccessToken(data) 
  const loginInfo = `$data&grant_type=password`;
  return fetch(`$API_URLToken`, 
    method: 'POST',
    headers: new Headers(
      'Content-Type': 'application/x-www-form-urlencoded',
    ),
    body: loginInfo,
  )
    .then((response) => response.json());

    // in your case set state to returned token


// use said token to authenticate request
export function requestUserInfo(token) 
  return fetch(`$API_URLapi/participant/userinfo`, 
    method: 'GET',
    headers: new Headers(
      Authorization: `Bearer $token`,
    ),
  )
    .then((response) => response.json());

我也会推荐:

    从 thunk 或 saga 调用 fetch,但这超出了问题的范围。

    无需将令牌放在隐藏字段中。顺便说一句,这仍然可以访问。只需保持状态即可。您还可以做一些其他的事情来保护它,但这也超出了问题的范围。

【讨论】:

我对发布的代码进行了一些修改。我将 fetch 放入一个函数中,现在在 onSubmit 事件中调用它。从 requestAccessToken 函数开始,$API_URLToken 会是我的 API 的 URL 并附加了令牌对象吗?例如theapi/api/authtoken。如果我们可以进一步讨论使用堆栈溢出聊天,请告诉我。我在想我在 fetchData 函数中设置的内容,可以使用您提供的 sn-p 来完成。 不,请参阅我的示例中的 headers: new Headers( 部分。 $API_URL 只是我网址的一部分。我要求用户信息,正文或网址中没有参数。我在标头中传递不记名令牌,它根据该令牌返回用户信息。 $token 然而,实际上是来自 api 的令牌。 我看到requestAccessToken有参数:data,data是包含对象的东西,就是用户的token。现在,- requestUserInfo 具有参数令牌。因此,为了获取 requestAccessToken 和 requestUserInfo 函数中包含的 fetch,$API_URL 应该是我在 FetchData 函数中使用的 API 的 URL 的一部分吗?我想了解的是这两个函数是如何访问我的 API 的。请求和身份验证函数中的 URL 是否会像这样设置:theapi/api/auth/$API_URLToken $API_URL = 'https://api.mywebsite.com/' 因此,当在第二个函数中组合时,它会解析为 https://api.mywebsite.com/api/participant/userinfo,它会返回有关用户的各种其他信息,例如前端需要的名字、姓氏、用户角色和 ID。跨度> 第一个函数是检索我的令牌并将其保存到会话存储中。第二个功能是在标头中使用该标记。我不再需要传递用户数据。 api 根据令牌知道谁在请求。

以上是关于React JS - 如何通过 fetch 语句验证凭据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 expo 中禁用 https-only fetch 请求 react native/node js

react与fetch

react-native——fetch

React - 实现fetch取消、中止请求

在序列中调用 React js Fetch 调用

在 React JS 中使用 fetch 处理响应状态