🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
OAuth

OAuth(Open Authorization)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

6501閲覧

TwitterOAuthで認証キャンセル時のエラー解決法

Yknd

総合スコア24

OAuth

OAuth(Open Authorization)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

1クリップ

投稿2016/11/10 11:28

###前提・実現したいこと
TwitterApiを使ったphpでの簡易ツイッター投稿フォームを作成しています。
ユーザーに既定のツイートをしてもらうキャンペーンでの利用を想定しています。

サイト閲覧者が投稿ボタンを押す
→OAuthでアプリ認証
→閲覧者のアカウントから既定のメッセージをツイート

という流れになります。

実装に当たっては、TwitterOAuth(Abraham)というライブラリを使っています。
https://github.com/abraham/twitteroauth

投稿自体は問題なく行えるのですが、2点ほどエラーが発生しており困っています。。
今回TwitterApiの利用がはじめてで知見に乏しく、お力添え頂けないでしょうか?

以下に該当のソースファイルも記載しておりますので、
長文となりますが、改善点などコメント頂けますと幸いです。

###実装環境

  • php5.4
  • OpenSSL support
  • TwitterOAuth ver.0.7.0

###Twitterアプリケーション設定

  • Access: Read and Write
  • Callback URL: http://***.com/test/twitter/src/callback.php
  • Callback URL Locked: No

###発生している問題・エラーメッセージ
1点目のエラーは以下の内容です。

投稿ボタンを押してOAuth認証ページ
https://api.twitter.com/oauth/authorize?oauth_token=***)
にリダイレクトさせる時点で発生します。

Fatal error: Can't use function return value in write context in /home/sites/heteml/users/***/test/twitter/src/TwitterOAuth.php on line 366

上記のエラーは以下該当箇所のコード削除で消えましたが、
根本的な解決にはならないため、修正したいと考えています。

php

1//↓TwitterOAuth.phpエラー該当箇所 2/* Remove CACert file when in a PHAR file. */ 3if (!empty(\Phar::running(false))) { 4 unset($options[CURLOPT_CAINFO]); 5}

2点目のエラーは以下の内容です。

投稿ボタンを押してOAuth認証ページ
https://api.twitter.com/oauth/authorize?oauth_token=***)
にリダイレクト後、「連携アプリを認証」ではなく「キャンセル」し、
「(アプリ名)に戻る」ボタンをクリックすると発生します。

Notice: Undefined index: oauth_verifier in /home/sites/heteml/users/***/test/twitter/src/callback.php on line 24 Fatal error: Uncaught exception 'Abraham\TwitterOAuth\TwitterOAuthException' with message 'Error processing your OAuth request: Invalid oauth_verifier parameter' in /home/sites/heteml/users/***/test/twitter/src/TwitterOAuth.php:138 Stack trace: #0 /home/sites/heteml/users/***/test/twitter/src/callback.php(24): Abraham\TwitterOAuth\TwitterOAuth->oauth('oauth/access_to...', Array) #1 {main} thrown in /home/sites/heteml/users/***/test/twitter/src/TwitterOAuth.php on line 138

こちらはエラー解消の目処が立っていません。

###今回のプログラムのソースコード
※twitterディレクトリは、TwitterOAuthの「twitteroauth-master」からリネームしたものです。

post.php

投稿ボタンの設置ページ。redirect.phpに飛ばす。

php

1<a href="twitter/src/redirect.php"><img src="img/tweet/post_btn.png" alt="投稿"></a>

twitter/src/redirect.php

Request Token、Request Secretを生成。Twitter認証ページのURLを作成し、リダイレクトする。

php

1<?php 2session_start(); 3 4require '../autoload.php'; 5require 'env.php'; 6use Abraham\TwitterOAuth\TwitterOAuth; 7 8/* TwitterOAuthを生成 */ 9$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET); 10 11/* Request Token、Request Secretを生成 */ 12$request_token = $connection->oauth('oauth/request_token', array('oauth_callback' => OAUTH_CALLBACK)); 13 14/* Request Token、Request Secretをsessionに保存 */ 15$_SESSION['oauth_token'] = $request_token['oauth_token']; 16$_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret']; 17 18/* Twitterと連携を行うURLを生成 */ 19$url = $connection->url('oauth/authorize', array('oauth_token' => $request_token['oauth_token'])); 20 21/* Twitterと連携を行うURLにリダイレクト */ 22header('Location: ' . $url);

twitter/src/callback.php

Twitter認証画面から戻って来た時にアクセスする。oauth_verifierからRequest Token、Request Secretの照合を行い、ユーザーの確認を行う。その後Access Token、Access Secretを生成。thanks.phpへリダイレクト。

php

1<?php 2session_start(); 3 4require '../autoload.php'; 5require 'env.php'; 6use Abraham\TwitterOAuth\TwitterOAuth; 7 8/* Request Token、Request Secretをsessionから取得 */ 9$request_token = array(); 10$request_token['oauth_token'] = $_SESSION['oauth_token']; 11$request_token['oauth_token_secret'] = $_SESSION['oauth_token_secret']; 12 13/* Request Tokenが間違っている場合はclearsessions.phpへリダイレクト */ 14if (isset($_REQUEST['oauth_token']) && $request_token['oauth_token'] !== $_REQUEST['oauth_token']) { 15 // 中断する。何かが違っている。 16 $_SESSION['oauth_status'] = 'oldtoken'; 17 header('Location: ./clearsessions.php'); 18} 19 20/* TwitterOAuthを生成 */ 21$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $request_token['oauth_token'], $request_token['oauth_token_secret']); 22 23/* Access Token、Access Secretを生成 */ 24$access_token = $connection->oauth("oauth/access_token", array("oauth_verifier" => $_REQUEST['oauth_verifier'])); 25 26/* Access Token、Access Secretをsessionに保存 */ 27$_SESSION['access_token'] = $access_token; 28 29/* 以降ではRequest Token、Request Secretは使用しないのでsessionから削除 */ 30unset($_SESSION['oauth_token']); 31unset($_SESSION['oauth_token_secret']); 32 33/* thanks.phpへリダイレクト */ 34header('Location: ../../thanks.php');

thanks.php

Twitter認証が完了した後にstatuses/updateでツイート投稿する。連携の前にアクセスされた場合はclearsessions.phpへリダイレクト。

php

1<?php 2session_start(); 3 4require 'twitter/autoload.php'; 5require 'twitter/src/env.php'; 6use Abraham\TwitterOAuth\TwitterOAuth; 7 8/* Access Token、Access Secretがsessionにない場合はclearsessions,phpへリダイレクト */ 9if (empty($_SESSION['access_token']) || empty($_SESSION['access_token']['oauth_token']) || empty($_SESSION['access_token']['oauth_token_secret'])) { 10 header('Location: ./twitter/src/clearsessions.php'); 11} 12 13/* Access Token、Access Secretを取得 */ 14$access_token = $_SESSION['access_token']; 15 16/* TwitterOAuthを生成(パラメータによって使用できる関数を制御) */ 17$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']); 18 19/* 認証済みアカウントから投稿 */ 20$status = $connection->post('statuses/update', ['status' => '投稿内容 投稿日: ' . date( 'Y/m/d H:i' ) . ' http://*****.com/test/']); 21?> 22 23/// 24/// 25<p>投稿が完了しました。ご応募ありがとうございます。</p>

twitter/src/clearsessions.php

セッションをクリアする処理。ログアウトや、エラーの時に使用。その後post.phpへリダイレクトする。

php

1<?php 2 3/* sessionsをクリア */ 4session_start(); 5session_destroy(); 6 7/* post.phpへリダイレクト */ 8header('Location: ../../post.php'); 9

twitter/src/env.php

Consumer KeyとConsumer Secret、Twitter公式サイトからのリダイレクト先であるcallback.phpのURLを定義。

php

1<?php 2 3define('CONSUMER_KEY', '---'); 4define('CONSUMER_SECRET', '---'); 5define('OAUTH_CALLBACK', 'http://*****.com/test/twitter/src/callback.php'); 6

###補足
同一ユーザーによる再投稿も想定していますが、
TwitterApiの仕様で同一ユーザーからの同一文言のツイートができないため、
statusにタイムスタンプを入れて対応しています。

少し不格好なツイートになるため他の回避策があればいいのですが・・

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しましたので、後学のために修正点を記載します。

1点目のエラー
PHPバージョンに起因したエラーでした。
現行のTwitterOAuthのgitソースはPHP5.5以上を想定しているため、
0.7.0→0.6.0にバージョンダウンすることで解決しました。

2点目のエラー
こちらは自作のcallback.phpのバグでした。

if (isset($_REQUEST['oauth_token']) && $request_token['oauth_token'] !== $_REQUEST['oauth_token']) { ↓ if (!isset($_REQUEST['oauth_token']) || (isset($_REQUEST['oauth_token']) && $request_token['oauth_token'] !== $_REQUEST['oauth_token'])) {

リクエストトークンが取得できていなくても中断されず、
TwitterOAuthを生成してしまっていました。

投稿2016/11/15 05:20

Yknd

総合スコア24

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問