尝试使用PHP中的cURL登录https://digitalgamingleague.co.za时遇到问题。代码的主要部分如下。我真的不知道如何使用cURL,因此,非常感谢anyhelp。
$username = get_option( 'wp_dgl_dgl_username' );
$password = get_option( 'wp_dgl_dgh_password' );
if (is_null($username) or is_null($password))
{
return "Please check the settings!";
}
//set the directory for the cookie using defined document root var
$dir = plugin_dir_path( __FILE__ );
//build a unique path with every request to store
//the info per user with custom func.
$path = $dir;
$cookie_file_path = $path."/cookies.txt";
$url="https://www.digitalgamingleague.co.za/";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
$start = curl_exec($ch);
$startinfo = curl_getinfo($ch);
$starterror = curl_error($ch);
curl_close($ch);
//login form action url
$url="https://www.digitalgamingleague.co.za/login/";
$postinfo = "password=" . $password . "&username=" . $username . "&remember=1&_from=https://digitalgamingleague.co.za/api/&_csrf=";
$request_headers = [
'Accept: */*',
'Accept-Encoding: gzip, deflate',
'Content-Type: application/x-www-form-urlencoded',
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($ch, CURLOPT_HEADER, true);
//curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_URL, $url);
//curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
//set the cookie the site has for certain features, this is optional
//curl_setopt($ch, CURLOPT_COOKIE, "cookiename=0");
//curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7");
//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
//curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_REFERER, $_SERVER['REQUEST_URI']);
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
//curl_setopt($ch, CURLOPT_AUTOREFERER, true);
//curl_setopt($ch, CURLOPT_FAILONERROR, true);
//curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
//curl_setopt($ch, CURLOPT_ENCODING, "");
//curl_setopt($ch, CURLINFO_HEADER_OUT, true);
//curl_setopt($ch, CURLOPT_MAXREDIRS , 30);
//curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postinfo);
$login = curl_exec($ch);
$logininfo = curl_getinfo($ch);
$loginerror = curl_error($ch);
curl_close($ch);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
//page with the content I want to grab
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, "");
//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_URL, "https://www.digitalgamingleague.co.za/api/cups");
//do stuff with the info with DomDocument() etc
$cups_raw = curl_exec($ch);
$info = curl_getinfo($ch);
$error = curl_error($ch);
curl_close($ch);
return "<strong>Start</strong>: <br>" . $start . "<br><em>Info</em>: <br>" . $startinfo . "<br><em>Error</em>: <br>" . $starterror . "<br><strong>Login</strong>: <br>" . $login . "<br><em>Info</em>: <br>" . $logininfo . "<br><em>Error</em>: <br>" . $loginerror . "<br><strong>Cups</strong>: <br>" . $cups_raw . "<br><em>Info</em>: <br>" . $info . "<br><em>Error</em>: <br>" . $error;
答案 0 :(得分:2)
你犯了几个错误,
你没有url编码用户名/密码,甚至硬编码的&from=https%3A%2F%2Fdigitalgamingleague.co.za%2Fapi%2F%26_csrf%3D
参数编码不正确(实际上应该是gzip and deflate
),修复它。或者使用urlencode(),或者更好,使用http_build_query。
您告诉服务器您接受accept-encoding: <all encodings that libcurl was compiled with here>
编码,但如果服务器决定使用任何这些编码,则您不提供解码它的代码。处理它的最好方法是将CURLOPT_ENCODING设置为emptystring,curl将自动'Content-Type: application/x-www-form-urlencoded',
,如果需要,可以为你解码。
您手动设置http 302 Found
标头,这不是必需的,并且容易出错,libcurl会自动检测x-www-form-urlencoded编码,并设置标头,如果您对网址进行编码正确(但你没有 - 见上面关于urlencoding的案例)
您需要会话cookie和csrf令牌才能发送登录请求,否则服务器将拒绝您的请求,认为它是CSRF黑客攻击尝试,并且您没有提供代码来获取csrf令牌。您应该使用html解析器(如DOMDocument)来提取它。
如果登录成功,服务器实际上会回复gbvyq1upya00nuu3@my10minutemail.com
重定向响应,但您没有提供代码来处理http重定向响应。处理这些问题的最简单方法是设置CURLOPT_FOLLOWLOCATION - 它存在于您的代码中,但仅限于注释中。
登录时不提供任何引荐来源标头,可能需要提供,您应该提供。使用CURLOPT_AUTOREFERER
这是一个工作示例,使用https://github.com/divinity76/hhb_.inc.php/blob/master/hhb_.inc.php中的hhb_curl类(而<?php
declare(strict_types = 1);
require_once ('hhb_.inc.php');
$hc = new hhb_curl ();
$hc->_setComfortableOptions ();
$hc->exec ( 'https://digitalgamingleague.co.za/login' ); // << getting a referer, csrf token, and a session.
$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
$csrf = NULL;
// extract the csrf token..
foreach ( $domd->getElementsByTagName ( "form" ) as $form ) {
if ($form->getAttribute ( "action" ) === '/login') {
foreach ( $form->getElementsByTagName ( "input" ) as $input ) {
if ($input->getAttribute ( "name" ) === '_csrf') {
$csrf = $input->getAttribute ( "value" );
break 2;
}
}
}
}
if ($csrf === NULL) {
throw new \RuntimeException ( 'failed to extract the csrf token!' );
}
$hc->setopt_array ( array (
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query ( array (
'_csrf' => $csrf,
'from' => '${param.from}', // << no idea what that's supposed to mean, probably a web dev error
'username' => 'gbvyq1upya00nuu3@my10minutemail.com',
'password' => 'gbvyq1upya00nuu3@my10minutemail.com',
'rememberMe' => 1
) )
) );
$hc->exec ( 'https://digitalgamingleague.co.za/login' );
hhb_var_dump ( $hc->getStdErr (), $hc->getResponseBody () );
帐户只是我为测试而创建的虚拟帐户,它受到危害并没有什么害处,这显然发生在我身上在这里发布凭证。)
import * as React from 'react';
import { connect } from 'react-redux';
// import {IAppState} from '../AppState';
interface IOwnProps {
id: string;
}
interface IMappedProps {
notNeed: number;
}
export interface IFooProps extends IMappedProps, IOwnProps { }
export class Foo extends React.Component<IFooProps, void> {}
// This function is just an example, yours may look different.
function mapStateToProps(state: IAppState): IMappedProps {
return {
notNeed: state.notNeed,
};
}
export default connect<IMappedProps, null, IOwnProps>(mapStateToProps, null,
)(Foo);
答案 1 :(得分:0)
当您为api(或服务器)编写客户端时,您必须手动完成浏览器所做的工作:保留标头并在请求中添加所有标头。