Yii2のauthclientでTwitterのpost系処理(バグを回避する)

もう少し詳しい内容をQiitaにアップしました。


とつぶやいたら @tanakahisateru さんが↓このヒントを教えてくれたので、
https://twittercommunity.com/t/post-request-returned-message-could-not-authenticate-you-code-32-after-migrated-to-api-v1-1/10264
authclientのソースを追って調べてみました。


結論から言うと、
yii\authclient\clients\Twitter
では今のところ、GET系の処理しか行えません。


POST系の処理を投げると

{"errors":[{"message":"Could not authenticate you","code":32}]}

というエラーレスポンスが返ってきます。


POST系の処理を行うには、親クラスである yii\authclient\OAuth1 の処理を一部書き換える必要があります。

使えるようにしたものを↓に置いておくので、yii\authclient\clients\Twitter の代わりにどうぞ。

<?php
use yii\authclient\OAuth1;

class Twitter extends OAuth1
{
    public $authUrl = 'https://api.twitter.com/oauth/authorize';
    public $requestTokenUrl = 'https://api.twitter.com/oauth/request_token';
    public $requestTokenMethod = 'POST';
    public $accessTokenUrl = 'https://api.twitter.com/oauth/access_token';
    public $accessTokenMethod = 'POST';
    public $apiBaseUrl = 'https://api.twitter.com/1.1';

    protected function initUserAttributes() {
        return $this->api('account/verify_credentials.json', 'GET');
    }
    protected function defaultName() {
        return 'twitter';
    }
    protected function defaultTitle() {
        return 'Twitter';
    }    
    
    protected function composeRequestCurlOptions($method, $url, array $params) {
        if ( $method === 'POST' && strpos($url, $this->apiBaseUrl) === 0 ) {
            $curlOptions = [];
            $curlOptions[CURLOPT_POST] = true;
            if (!empty($params)) {
                $curlOptions[CURLOPT_POSTFIELDS] = http_build_query($params);
            }
            $authorizationHeader = $this->composeAuthorizationHeader($params);
            if (!empty($authorizationHeader)) {
                $curlOptions[CURLOPT_HTTPHEADER] = ['Content-Type: application/x-www-form-urlencoded', $authorizationHeader];
            }
            return $curlOptions;
        } else {
            return parent::composeRequestCurlOptions($method, $url, $params);
        }
    }
}

メソッドの継承とかオーバーライド(っぽい事)

ケース:
3rd party ライブラリの実装を利用しつつも一部のメソッドだけ書き換えたい。

具体的には、Aというインターフェースを実装したAImplのメソッドをオーバーライドしたい。

こういう場合は、AImplを匿名フィールド(埋め込みフィールド)として持つBImplを作ってやれば、AImplを継承しつつメソッドをオーバーライドする(かのような)事ができる。

(↓)こんな感じで。

http://play.golang.org/p/9EjYiAj3YQ

package main

import "fmt"

type A interface {
	Hoge() string
}

type AImpl struct {
	value string
}

func (self AImpl) Hoge() string {
	return "This is generated in AImpl.Hoge(), value is " + self.value
}

type BImpl struct {
	AImpl
}

func (self BImpl) Hoge() string {
	original := self.AImpl.Hoge()
	overwritten := original + " ; This is added in B.Hoge(), value is " + self.value + "!"
	return overwritten
}

func main() {
	var a A
	a = BImpl{AImpl{"yeah"}}
	fmt.Println(a.Hoge())
}

出力:This is generated in AImpl.Hoge(), value is yeah ; This is added in B.Hoge(), value is yeah!

今メインで取り組んでることのアピール

もしあなたやあなたの家族が「家造り」や「リフォーム」を思い立ったなら、どこのハウスメーカーor工務店さんに頼もうとするか・・・? たぶん人生の中でも大きな買いものだし、何度もあることじゃないから経験なんてなくて、よくわからない。 判断の材料になるのは、つき詰めれば「信頼できる相手かどうか」という点に尽きるんじゃないかと思います。

ネットなら、SUUMOやHOMESで検索すれば、すごい数のハウスメーカー工務店がリストアップされるんだけど、でもそれで何かを決められるわけでもなく、相場を知るためにたくさん資料請求だけして、けっきょくは「知人の紹介」や「近い」お店ににおっかなびっくり足を運ぶっていうのは、良くあるパターンみたい。

僕らCoumfyは、そうじゃなくて、どうすれば信頼できる工務店を(ネットでも)探せるのかという課題を解決していこうと考えて、このサイト作りに取り組んでます。

まずは大阪周辺から始めて、まだ掲載10店(&掲載準備中10数店)ですが、がんばってもっと広げていくよ。

どうでもいいこと

なんかエンジニア探す時に特定の言語の経験や実績を問う人って多いんだけど、あれってだいぶ的外れだと思うよね。まともなエンジニアなら初めて触る言語でもすぐ使いこなせるもんだし、それが出来ない人はそもそも自フィールドでもマトモなモノ創りは出来ないと思うし。。。

Go言語でウェブ開発した感想

Go言語でウェブ開発する機会があったので、かるく感想。

2人コンビで、まぁだいたい2週間で設計して、2週間でざっくり作って、2週間かけて細部の作りこみ・バグ取り・運用環境構築を並行しながらデザイナー&オペレーターへの引き継ぎ、ていうスケールで。

自身、Goは全く初めて触る言語だけど、まぁ良くも悪くも「素直」な処理系ですね。ウェブ開発周りでフルスタックの経験があれば、ゼロから2日もあればほぼ把握して、3日目にはもうトップギアガリガリ開発できる感じ。
最初はポインターやらprintfやら懐かしい!、とか思いながらいじり始めて、しかし標準でウェブ開発の一式が揃ってるのは今時の世代っぽいなぁ、とか思いながら、調子が乗って来ると、ありゃ、まだまだ発展途上の言語だなぁとか感じる部分もポロポロ出てくる、という具合。
あと、「日本語の情報があんまりない」ってのはまぁその通りだけど、そもそも根が素直っていうか単純っていうか単細胞(これは言い過ぎか^^;)な処理系なので、わざわざ日本語の情報を探す必要は案外出てこないんじゃないかとは思います。

手触り感としては、RoRなどとは丸っきり真逆で、でもJavaほどガッツリな雰囲気もない。・・・うん、決して悪くはないです。生粋のエンジニアのチームでやる分には、むしろスピード乗るかもしれない。Java系とLL系の対局軸の間で、意外にGoがしっくりくるというパターンはあるかもな。