React JS - 如何通过 fetch 语句验证凭据 [英] React JS - How to authenticate credentials via a fetch statement

查看:17
本文介绍了React JS - 如何通过 fetch 语句验证凭据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是创建一个运行 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';从 'react-dom' 导入 ReactDOM;导入'./Login.css';从'react-router-dom'导入{ withRouter };类登录扩展组件{构造函数(){极好的();this.state = {数据: [],用户名: "",密码: "",令牌:"",};}//结束构造函数componentWillMount() {}componentDidMount() {this.fetchData();}取数据(){获取('http://theapi/api/auth', {方法:'POST',标题:{'内容类型':'应用程序/json',},正文:JSON.stringify({用户名:'我的用户名',密码:'我的密码',授权:'TheReturnedToken',})})/* 结束提取 */.then(results => results.json()).then(data => this.setState({ data: data }))}//请求令牌请求访问令牌(数据){const loginInfo = '${data}&grant_type=password';return fetch('${API_URL}Token', {方法:'POST',标题:新标题({'内容类型':'应用程序/json',}),正文:登录信息,}).then((响应) => response.json());}//验证请求请求用户信息(令牌){return fetch('${API_URL}api/participant/userinfo', {方法:'获取',标题:新标题({授权:'Bearer ${token}',}),}).then((响应) => response.json());}改变 = (e) =>{this.setState({[e.target.name]: e.target.value});};//结束更改onSubmit = (e) =>{this.fetchData();e.preventDefault();//console.log(this.state);this.setState({用户名: "",密码: "",});this.props.history.push('/登陆');};使成为() {控制台日志(this.state.data);返回 (<div><div className="loginContainer"><h2>会员登录</h2><表格><输入id="用户名"名称=用户名"占位符=用户名"值={this.state.username}onChange={e =>this.change(e) }className="表单控件"/><br/><输入id="密码"名称=密码"类型=密码"占位符=密码"值={this.state.password}onChange={e =>this.change(e) }className="表单控件"/><br/>

);}}导出默认 withRouter(Login);

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

解决方案

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

//请求令牌//订阅此事件并使用返回的 json 将您的令牌保存到状态或会话存储导出函数 requestAccessToken(data) {const loginInfo = `${data}&grant_type=password`;return fetch(`${API_URL}Token`, {方法:'POST',标题:新标题({'内容类型':'应用程序/x-www-form-urlencoded',}),正文:登录信息,}).then((响应) => response.json());//在您的情况下,将状态设置为返回的令牌}//使用所述令牌来验证请求导出函数 requestUserInfo(token) {return fetch(`${API_URL}api/participant/userinfo`, {方法:'获取',标题:新标题({授权:`Bearer ${token}`,}),}).then((响应) => response.json());}

我还建议:

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

  2. 无需将您的令牌放在隐藏字段中.顺便说一句,仍然可以访问.保持它的状态.您还可以采取其他措施来稍微保护它,但这也超出了问题的范围.

My goal is to create a React JS login page that runs off a json Rest service. In Postman, when I enter the URL for the service, set it to run as POST and enter the following JSON into the body: {username: "myUserName", password: "myPassword"} ...a token is returned. So in my fetch clause, I'm using JSON.stringify to pass the username and password to the server.

I'm new to using Fetch with react, So my question is, how do I get started in authenticating various users, just using react JS with fetch only? I assume, I'm to write my logic within the second then of my Fetch clause?

Currently, my page accepts any credentials and routes the user to a landing page upon clicking the submit button. I have a function containing fetch and now calling the fetch function once the onSubmit button is clicked, which now grabs the token.

This is my code:

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_URL}Token', {
          method: 'POST',
          headers: new Headers({
            'Content-Type': 'application/json',
          }),
          body: loginInfo,
        })
          .then((response) => response.json());
      }

      //authenticate request
      requestUserInfo(token) {
        return fetch('${API_URL}api/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);

How do I get started in getting my form to authenticate various users? Basically, I'm attempting to have my page to accept a username and password and if the two match, and then route the user to a landing page.

解决方案

Don't put your authorization token in the body. Put it in the Headers. The first function is going to pass in username, password, and authentication type (ie grant_type=password). Then my second function is going to use that to authenticate the request. There is no longer a need to pass any user information, because my api knows who is requesting based on the token that is passed in. The current documentation for OAuth 2.0 is here, and you can find more information about using headers with 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_URL}Token`, {
    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_URL}api/participant/userinfo`, {
    method: 'GET',
    headers: new Headers({
      Authorization: `Bearer ${token}`,
    }),
  })
    .then((response) => response.json());
}

I would also recommend:

  1. Calling fetch from a thunk or a saga, but this is out of scope of the question.

  2. No need to put your token in a hidden field. Which is still accessible btw. Just keep it in state. There are other things you can do to secure it a little, but this too, is out of scope of the question.

这篇关于React JS - 如何通过 fetch 语句验证凭据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆