PHP cURL登录网站

时间:2017-05-19 14:28:38

标签: php wordpress curl

尝试使用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;

The Mostly Source Code

2 个答案:

答案 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(或服务器)编写客户端时,您必须手动完成浏览器所做的工作:保留标头并在请求中添加所有标头。