Laravel の twitter Oauthの設定

現在G's Academy というプログラミング学校に週末通っており、そこでPHPフレームワークLaravelを利用しています。

Laravelは認証系の仕組みがコマンド打つだけであっという間にできてしまい楽勝だったので、色気を出してtwitterOauth認証に手を出してハマってしまいました。 その時のメモです。

twitter API

まずはTwitterAPIキーを取得するために公式サイトでの設定が必要です。

https://apps.twitter.com/

Laravel Socialiteを使っています。

公式URL Laravel Socialite - Laravel - The PHP Framework For Web Artisans

参考URL

https://php-junkie.net/framework/laravel/socialite/ https://qiita.com/KeisukeKudo/items/18dd8a342a4bdd43913c

他にも ' laravel socialite twitter 認証' などでググると結構情報は出てきます。

インストールと初期設定

まずはsocialiteをインストールします。コンソールにて

>composer require laravel/socialite

twitter developersにて取得したAPIキー等は.envに記載

TWITTER_API_KEY = ''; //Consumer Key (API Key)
TWITTER_API_SECRET = ''; //Consumer Secret (API Secret)
TWITTER_CALLBACK_URL= 'http://xxxxxx' 
TWITTER_ACCESS_TOKEN = "";
TWITTER_ACCESS_TOKEN_SECRET = "";

上記は全てtwitter developersで取得した値と一致する必要があります。callback_urlは自身でせってしなければなりませんが、とりあえずは localhost 指定でも大丈夫なのでログイン後に遷移する先のルーティングを指定してください。

続いてconfig/services.phptwitter APIのキー設定を追記。これでモジュール内で.env内から具体的な値にアクセスすることができるようになります。

'twitter' => [
        'client_id'     => env('TWITTER_API_KEY'),
        'client_secret' => env('TWITTER_API_SECRET'),
        'redirect'      => env('TWITTER_CALLBACKURL'),
    ],

 モジュールの設定

twitterのログイン認証を行う実行先のルーティングを指定します。
web.phpにルート情報を追加します。下記は私の例ですので任意のルーティングで大丈夫です。以下自身の設定に合わせて読んでください。

Route::get('login/twitter', 'Auth\LoginController@redirectToTwitterProvider');
Route::get('login/twitter/callback', 'Auth\LoginController@handleTwitterCallback');

app/http/Controllers/Auth/LoginController.php にメソッド追加

use Laravel\Socialite\Facades\Socialite;

// 途中略

public function redirectToTwitterProvider() {
       return Socialite::driver('twitter')->redirect();
}

config/app.php の該当箇所に以下を追加

'providers' => [
    // これを追加
    Laravel\Socialite\SocialiteServiceProvider::class,


'aliases' => [
  // これを追加
  'Socialite' => Laravel\Socialite\Facades\Socialite::class,

以上の設定で /login/twitter のルートにアクセスすると自動的にtwitterの認証画面に遷移します。
そしてそこでログイン処理をすると上記で設定したcallback先に自動的に遷移します。素晴らしい。

 ユーザ情報の取得&ハマりポイント

ログイン処理後twitterからユーザ情報を取得します。一応公式や参考URLには

$user = Socialite::driver("twitter")->user(); 

で取得できるとありますが、何度やってもエラーになります。ここで結構ハマってしまいました。

※補足:その後サーバにデプロイしたケースでは上記の取り方でうまく行きました。エラーはローカル環境の時だけ起こることがわかりました。

他のSNSgoogle経由では大丈夫みたいですが、twitterはうまく行きませんでした。
そこでエラーの発生場所のソースコードを見てみると原因は SocialiteのAbstractProvider.php 内にありました。

protected function hasNecessaryVerifier()
    {
        return $this->request->has('oauth_token') && $this->request->has('oauth_verifier');
    }

原因はrequest に auth_token, oauth_verifier が設定されていないからのようです。
本来ならcallbackしてきたあとで自動で設定されるはずのようなのですがうまくいかずのようです。しかしこちらではすでに上記の情報は既知であるので、 直接代入して設定することにしました。

$token = env('TWITTER_ACCESS_TOKEN');
$secret = env('TWITTER_ACCESS_TOKEN_SECRET');

$user = Socialite::driver('twitter')->userFromTokenAndSecret($token, $secret);

Laravel Socialite公式にトークン等の設定する値が分かっている場合は上記のように設定しましょうとの説明がありました。

Laravel Socialite - Laravel - The PHP Framework For Web Artisans
Socialiteを使ってLaravelでTwitterログイン機能を実装 - Qiita

これでユーザ情報を取得できるはずです。しかし!
このようにしてtwitterからユーザ情報を取得した際に、emailが取れていないかもしれません。それはtwitter api の設定時にprivacy policy とterms_of_service のURLを設定していないからです。
それらを設定すればemail取得の許可の設定チェックボックスが表示され、それをオンに設定すればメール情報を取得することができます。以下参考。

omniauth-twitterでemail情報を取得する - Qiita

ユーザ情報の登録

twitterからログインしてきたユーザが新規であった場合は取得したユーザ情報をデータベースに登録します。 基本ユーザはemailでユニークにしたい。そしてtwitter経由登録の場合はパスワード無しになるのでusersテーブルのpasswordはnullableに変更する必要があります。

そこでUsersテーブルのpasswordをnullableに変更するためmigration

> php artisan make:migration change_password_users_table

migrationファイルの中

public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            //passwordカラムにnullを許可
            $table->string('password')->nullable()->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('password')->nullable(false)->change();
        });
    }

migrationの実行

>php artisan migrate

migrationでテーブルのカラム変更が初めての場合はエラーになるので、以下をインストールしてからmigrateを再実行しましょう。

> composer require doctrine/dbal

基本的にはメールアドレスでユーザの判断をしますが、twitter id も併用するように私はしました。
理由はtwitterに紐づいたemailが変更された時を考えてのことです。(あらゆるケースを想定しだすと何がベストか迷いますが、ひとまずそのように判断)。

その為にUserテーブルにtwitter_id に対応したカラムを追加しました。これは通常のmigrationで対応可能。

そして実際にデータベースの更新をしますが、Userのデータベース更新メソッドは特殊なようです。
単純に User::find や User::where で取得したオブジェクトに対してsaveメソッドを実行してもエラーになります(メソッドがないと怒られます)。
一旦ログイン操作をしてからfindやwhereするとうまくいきます。

$user = User::where('twitter_id', twitter_idの何か)->get();
$user->email = xxx@yyy.com; // 取得したemailの設定

 // ダメなパターン
$user->save(); // このままではエラーになる 

// good!
Auth::login($user); // これをやってから
$user->save();  // saveがうまくいった

ちなみに上記処理をLoginControllerでやっている場合はAuthを呼び出しているか注意(下記)。

use Illuminate\Support\Facades\Auth;
use App\User;

上記のsave方法以外にUserには、firstOrCreate メソッドがあり、これは上記のlogin操作なしでも使えます。
このメソッドでは、第一引数で検索して見つかればselect 、なければ第二引数と合わせてcreateし、Userのオブジェクトを返します。

$user = User::firstOrCreate(
 ['email'=> $user_info->email], // これで検索 第一引数 あれば$userに検索結果を返す
 ['name' => $user_info->name, 'twitter_id'=>$user_info->id,
                'img_url'=>$user_info->avatar]); // 第一引数で存在しなければこれも合わせてcreateし、新たなユーザを$userに返す

Auth::login($user); // その後の操作用にログイン

以上で一通り完了。あとは通常ログインユーザと同様に動くはずです。お疲れ様でした。

文春野球学校

今月から「文春野球学校」の生徒となった。 教室では「野球コラムの書き方、教えます!!」と題して以下の活動を行っている。

  • 野球ライターの方々の講座@文芸春秋社
  • メンバーのSNSサイトへの参加、各メンバーの記事の投稿
  • 講座後の交流戦(飲み会)

 私は野球ライターになりたくて参加しているわけではないけれど、文春野球のサイトを見て楽しかったのと、 日ごろ自分の周りに少ない野球好きの人たちと交流できるかなと思って参加した。 まあ、一応自分が書いた 文章を人に読んでもらいたいという気持ちもある。

 少し実務的な話だと、日頃仕事に関連する文章しか書かないし、ブログも面倒でめったに更新しないので、 日頃業務で書く文章とは違う楽しみや感情のある文章の書き方を学ぶこと、筆不精も改善されるのではという点 が狙いとしてはある。

 実際にこうしてブログを更新しようという気になっているので役に立っているのかもしれない。

 先日1回目の講座に参加してきた。講師は最近「野球消滅」を出された中島大輔さん。

野球消滅 (新潮新書)

野球消滅 (新潮新書)

 
 

 テーマは「批評精神」でためになる話を伺うことができた。グループディスカッションがあったり、 その後交流戦に望んだりで楽しい時間をすごした。とにかく他メンバーのファン球団愛には結構圧倒された。 講座は月一で投稿は随時なので継続していこうと思う。

また来年春くらいにトライアウト(募集)があるようなので興味のある方はいかがでしょうか。

bunshun.jp

※このブログでもそこで書いた文章を載せようかと思っています。仕事とは関係ないけど興味のある方はご覧ください。

python入門第1回終了

知財の人のためのpython入門の第1回を開催しました。

7名の方に参加いただき盛況でした。

写真載せたかったですがその後の飲み会のものしかなかったので次回取ってアップロードしたいと思います。

 

 内容はデータ型、for, if, whle などの制御文が中心で基本的な内容でしたが、説明するといろいろ項目が多く、2時間を予定していましたが少しオーバーして終わりました。参加者のプログラミング経験にばらつきがありましたが演習問題を多めにかつ難易度も易からやや難までそろえていたのでそれぞれが楽しめたようです。

 参加者の方からは今日やった内容で特許の実務に役立つイメージがわかないという話がありましたが、現状では文字列処理、ファイル操作もまだなので仕方ないのかなとは思います。その段階になればサンプルとしてこのサイトかpython用のサイト(こちら)

にアップしたいと思います。

 次回は12/17を予定しています。引き続き続けていきたいと思います。

知財の人のためのPython サイト

先日募集していた「知財の人のためのPython入門」にあわせてサイトを立ち上げました。

講座の内容やそれに関する情報を残していこうと思います。

 

知財の人のためのPythonサイト

f:id:tomoro_azu:20181118210542p:plain

「一発リンクトモロヲ君」の思い出

「退屈なことはpythonにやらせよう」のまえがきに筆者の友人の経験談についての話があった。

 その友人は大学時代、家電量販店で他店と自店舗の価格比較を紙ベースで突き合わせて比較し、競合店の方が安い商品をピックアップするという作業をしていた。そしてその作業に丸2日かかっていた。そして別の友人からの助言でデータを処理するプログラムを数時間で作成し、作業は数秒になった。とのこと。

 

 これを読んで自分が特許業界に入ったすぐの時のことを思い出した。まだ何も業界のこともわからず右往左往しながらときに手を持て余すこともあった。そんな時アルバイトの人がエクセルで何か一生懸命作業しているので聞いてみると、公報のPDFにハイパーリンクを張っているとのこと。その件数3000件。その2か月前までプログラマだった私は衝撃を受け「なにをしとるんじゃ~」と思い、そして自分でもこれなら役に立てると思い、上司にその仕事を引き受けさせてほしいと願い出た。そしてまったくエクセルのVBAを触ったことはなかったが、ネットで調べながら自動的にリンクを作成するマクロを作成した。作業は数秒になった。

 意外に他の同僚にも好評で配布することになり、ファイル名を「一発リンクトモロヲ君」と名付けて配布し、自身が退職するときにもファイルは配布していたのでそのまま残った。

 

 それから十数年後のつい先週(上記の書籍を買う数日前)に特許情報フェアで当時の同僚(今もその会社にいる人)に偶然会った。久しぶりなのでちょっとお茶でもと誘って話していると他の同僚だけど私が退職後に入社した、会ったことのない方が合流した。するとその方が「あのトモロヲ君の作者ですか~、お世話になってます!」というではないか。なんとまだ現役で使われているらしい。なんか恥ずかしいやらおかしいやらいろんなことを思ったが話は盛り上がった。一番おかしかったのが「名前にインパクトがあって忘れない」ということだった(ファイル名変えてないんかい!とは思った)。

 どうやら私が手を持て余して作ったトモロヲ君は私のいないところで多くの「退屈なこと」をやったらしい。

 

 で、そのインパクトのある名前も当時は「またまたふざけて~」「サムい」などいろいろ言われたのだけど結構思い入れがありまして。

 その昔プログラマ時代にとっても火を噴いているプロジェクトがあって、時間的にも肉体的にも限界に近い状況。あるときデータベースの処理に皆困っていて、プロジェクト側の身内で使うツールが必要となったものの、だれも手を出せない状況。そんな中、一番忙しいはずのリーダーから「たまにはプログラムしたくてね~、こんなんつくちゃったよ」とエクセルVBAで作ったファイルが配布された。その出来は素晴らしく、そしてどこにそんな時間が?わずかしかない自分の時間を皆のために使ったのではと驚いた。そしてそのファイル名は皆に気を使わせないようにしたのか真意は定かではないが「一発タナカ君」。

 その精神を少しでも受け継げたらと思って特許業界新人のときに思って付けた(パクった)ファイル名なのだった。

 

 あれから十数年。自分で使うことはないがその気持ちを忘れないようにと「一発リンクトモロヲ君」はPCを買い替えても中に置くことにしている。そして一人会社となった今、手助けする同僚はいない。

 

トモロヲ君の画面紹介

 デザインはいまいち。。ほしい人がいたら許可もらって配布しようかな。

f:id:tomoro_azu:20181116101408j:plain

 正規表現を使ってファイル名のパターンを自由に定義できるように対応

 どのデータベースのファイルでも外国の公報でも対応できる。

f:id:tomoro_azu:20181116101503j:plain

python勉強会

なんとか勉強会は希望者が6名集まり開催にこぎつけることができました。

ただ、ほとんどはプログラム自体が初めてという人なのでどう進めるか悩み中。

 

特になにか書籍を使ったほうがよいかと思うのでどれにしようかと悩む。

結局何かやりたいことがあってプログラムはその手段であるのでそういう意味だとこれかな。 少し基本をさらったらデータベースからダウンロードしたエクセルやcsvを処理して集計とか一気にやるほうが実務に役立つ実感が得られそうですし。

 

退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

 

ただ、これ600ページもあるんですね。。これ買って持参というのは厳しいしやる気がなくなるのは間違いない。 実物を明日丸善に見に行ってみよう。

 

特許情報フェアe-patent トークセッション

11/7 特許情報フェア にてe-patentのトークセッションに参加しました。

結構聞いてくださる方がおり大変ありがたかったです。youtubeで見た方からも

連絡いただきました。ありがとうございます。

ライブ配信はありましたが録画はあるかはわかりませんのでe-patentのサイトでチェックしてください。

f:id:tomoro_azu:20181108113747j:plain

 開始前の様子です

 

その時のスライドを共有させていただきます。スライドだけではセッション時の

内容がわかりにくいかもしれないので手書きのメモも一緒にアップします。見ずらい

かもしれませんがご参考までに。

ちなみに最後にあるプログラミング入門はセッション時には触れていません(笑)。募集はしておりますのでよろしくお願いいたします。

 

www.slideshare.net

 

www.slideshare.net

 

ーーーー  募集 -----

知財技術者のためのpython入門」

    ・数名集まったら開催したい

 ・python初心者あるいはプログラム初心者

  (経験者で教えたいという方も是非)

 ・費用:無料

 ・月2回くらい 2019年1月以後開始予定

  ・目標:ファイル(csv,excel,xml,text)の処理

     いずれはクローリングやwebアプリも