我使用 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+\\"
}
}
}
从高层次来看,您希望将输入值连接到反应状态。您发布的文档链接描述了如何执行此操作。也许只是尝试 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个主要步骤:
您是否有更具体的方面需要帮助?
您收到 CORS 错误。请参阅 https://www.mediawiki.org/wiki/API:Cross-site_requests 了解如何向 MediaWiki API 发出 CORS 请求。
我只会使用状态来处理用户名和密码数据的传输。我在下面添加了工作代码。 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;