如何调用API来登录?

问题描述 投票:0回答:3

我使用 MediaWiki 作为我的后端,并且它在“localhost/name”上运行。

我的login.js文件:

import React, {useState} from 'react';
import axios from 'axios';

function Login()  {

    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');

    async function login() {
        console.log(username, password);

        let url = 'http://localhost/wikimedia/api.php';

        let params = {
            action: "query",
            meta: "tokens",
            format: "json",
            type: "login"
        };

        // fetch login
        const response = await axios.get(url + '?' + params + '&origin=*');

        console.log(response);

        let loginToken = response.data.query.tokens.logintoken
        let cookie = response.headers['set-cookie'].join(';');

        let body = {
            action: 'login',
            lgname: username,
            lgpassword: password,
            lgtoken: loginToken,
            format: 'json'
        }

        let bodyData = new URLSearchParams(body).toString();

        axios.post(url, bodyData, {
            headers: {
                Cookie: cookie,
            }
        }).then(response => {

            let cookie = response.headers['set-cookie'].join(';')
            console.log(response.data);
        })
    }

    return (
      <div>
        <h1>Sign In</h1>
        <input 
            type="text"
            onChange={(e) => setUsername(e.target.value)}
            placeholder="username"
        />
        <br/>
        <input
            type="password"
            onChange={(e) => setPassword(e.target.value)}
            placeholder="password"
        />
        <br/>
        <button onClick={login} type="submit">Login</button>
      </div>
    )
  };
  
  export default Login;

但是,我收到以下响应,这不是文档中预期的响应:

{
    "data": "a-bunch-of-irrelevant-stuff",
    "status": 200,
    "statusText": "OK",
    "headers": {
        "cache-control": "private, must-revalidate, max-age=0",
        "content-language": "en",
        "content-type": "text/html; charset=utf-8",
        "expires": "Thu, 01 Jan 1970 00:00:00 GMT",
        "mediawiki-login-suppressed": "true"
    },
    "config": {
        "transitional": {
            "silentJSONParsing": true,
            "forcedJSONParsing": true,
            "clarifyTimeoutError": false
        },
        "transformRequest": [
            null
        ],
        "transformResponse": [
            null
        ],
        "timeout": 0,
        "xsrfCookieName": "XSRF-TOKEN",
        "xsrfHeaderName": "X-XSRF-TOKEN",
        "maxContentLength": -1,
        "maxBodyLength": -1,
        "env": {},
        "headers": {
            "Accept": "application/json, text/plain, */*"
        },
        "method": "get",
        "url": "http://localhost/wikimedia/api.php?[object Object]&origin=*"
    },
    "request": {}
}

到目前为止,我正在将第一个 fetch -> 令牌的响应记录到控制台,但我没有得到预期的响应:

{
    "batchcomplete": "",
    "query": {
        "tokens": {
            "logintoken": "9ed1499d99c0c34c73faa07157b3b6075b427365+\\"
        }
    }
}
reactjs mediawiki mediawiki-api
3个回答
2
投票

从高层次来看,您希望将输入值连接到反应状态。您发布的文档链接描述了如何执行此操作。也许只是尝试 console.logging 状态值以响应输入更改,以确保输入正确连接。

一旦您获得了状态上可用的输入值,您可能需要使用用户名和密码调用 getToken 方法。关于事件的 React 文档描述了如何响应按钮单击或表单提交等事件。 https://reactjs.org/docs/handling-events.html

我的假设是,在调用 getToken 之后,您会希望使用检索到的令牌登录。因此,使用用户名、密码和令牌调用该方法。

您可能需要对 javascript 承诺有基本的了解,才能了解如何排序调用,即仅在从 getToken 获得响应后调用登录

https://web.dev/promises/ https://javascript.info/promise-basics https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

所以3个主要步骤:

  1. 将表单连接到状态
  2. 提交表单后,调用 getToken,传递用户名和密码(您在步骤 1 中获得)
  3. 收到 getToken 的响应后,进行新的登录调用,传递用户名、密码和令牌(您从步骤 2 中获得)

您是否有更具体的方面需要帮助?


1
投票

您收到 CORS 错误。请参阅 https://www.mediawiki.org/wiki/API:Cross-site_requests 了解如何向 MediaWiki API 发出 CORS 请求。


0
投票

我只会使用状态来处理用户名和密码数据的传输。我在下面添加了工作代码。 doSomethingWithCreds 函数可用于将您的数据传输到某个路由,并最终将令牌绑定到它。

我强烈建议您花时间学习状态以及一些通用的钩子,例如 useRef 和 useEffect。这将使开发和理解 React 中的一些关键主题变得更加容易。

状态文档参考

import {useEffect, useState} from 'react'
import './App.css';

function App() {

  const[pass,setPass] = useState()
  const[user,setUser] = useState()

  const handlePassChange = event =>{//Updates pass every time a new char is entered instead of on submit
    setPass(event.target.value)
  }

  const handleUserChange = event =>{
    setUser(event.target.value)
  }
  
  const doSomethingWithCreds = () =>{
    console.log('password: ' + pass)
    console.log('user' + user)
  }

  return (
    <div className="form">
      <h1>Login Page</h1>
      <form>
        <div className="input-container">
            <label>Username </label>
            <input onChange={handleUserChange} type="text" name="uname" required />
        </div>
        <div className="input-container">
            <label>Password </label>
            <input onChange={handlePassChange} type="password" name="pass" required />
        </div>
        <div className="button-container">
            <input onClick={doSomethingWithCreds} type="submit" value="Login" />
        </div>
      </form>
    </div>
  );
}

export default App;
© www.soinside.com 2019 - 2024. All rights reserved.