22
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravel Socialite用のYahoo JAPAN ID(YConnect)ドライバ実装

Last updated at Posted at 2016-02-18

まず、Socialiteの一般的な使い方はこちらをどうぞ。

Laravel Socialiteはすごい便利ですね。但し、標準のドライバがあれば。。。
多くの場合、標準対応の、

  • Facebook
  • Twitter
  • Google+

あたりで事足りるのですが、ある案件で「YahooのIDに対応しろ!」と言われそうなので、調べてみました。

##独自実装までの経緯

まず、「socialite yahoo」でググッてみると、直ぐに、Yahoo用のドライバに行き着いた。どやら、Yahoo以外にも主要なサービス用のものが勢揃いしているよう。。。

とはいえ、海外サービスばかり。ご存知、Yahoo JAPANも、かなり独立性が高いので、認証の仕組みも違うかなと・・・と調べて見たところ、やはり本家とJAPANではずいぶん仕様が違うようで使えそうにありません。

独自に実装するしか無いか・・・と調べていたら、ドンピシャな記事が。

これで一安心と、喜んだのもつかの間。OAuth1.0とOAuth2.0では、少し実装の仕方が異なる感じ(記事は1.0でYahooは2.0)。

仕方がないので、調べながら実装してみると何とかemailやIdを取得できるところまでは動いたのでメモしておきます。
あまりLaravelの仕組みを理解していないままいじってるので、おかしいところがあるかもしれません。

##前提

LaravelやらSocialiteは既にインストールされていることを前提として進めます。

##実装

先人の記事にならい、app以下にSocialiteというフォルダを作り、そこで作業することにしました。もちろん、他の場所でも問題ありません。

###YahooJpProvider

1.0では、classの実装が必要なようですが、2.0では基本、Providerだけ実装すればいいようです。
他の、Providerの記述や、Yahooの仕様ページを参考に、必要なパラメーターやメソッドをオーバーライドしていきます。

YahooJpProvider.php

<?php

	namespace App\Socialite;

	use Laravel\Socialite\Two\AbstractProvider;
	use Laravel\Socialite\Two\ProviderInterface;
	use Laravel\Socialite\Two\User;

	class YahooJpProvider extends AbstractProvider implements ProviderInterface
	{

		//scopeの区切り文字設定
		protected $scopeSeparator = ' ';

		//スコープ設定
		protected $scopes = [
	        'openid',
	        'profile',
	        'email',
	    ];

		//認証用URL($stateはオプション)
		protected function getAuthUrl($state)
	    {
	        return $this->buildAuthUrlFromBase('https://auth.login.yahoo.co.jp/yconnect/v1/authorization', $state);
	    }

	    //token取得用URL
	    protected function getTokenUrl()
	    {
	        return 'https://auth.login.yahoo.co.jp/yconnect/v1/token';
	    }

	    //Token取得の際のオプション
	    //Basic認証と必要なPOSTパラメータを送付
	    public function getAccessToken($code)
	    {
	    	$basic_auth_key = base64_encode($this->clientId.":".$this->clientSecret);

	        $response = $this->getHttpClient()->post($this->getTokenUrl(), [
	        	//認証
	        	'headers' => [
	        		'Authorization' => 'Basic '.$basic_auth_key,
	        	],
	            // 'form_params' => $this->getTokenFields($code),
	            // 直接記述
	            'form_params' => [
	            	'grant_type' => 'authorization_code',
	            	'code' => $code,
	            	'redirect_uri' => $this->redirectUrl
	            ],
	        ]);

	        return $this->parseAccessToken($response->getBody());
	    }

	    //ユーザー情報取得
	    protected function getUserByToken($token)
	    {
	    	//url + schema=openidが必要だった
	        $response = $this->getHttpClient()->get('https://userinfo.yahooapis.jp/yconnect/v1/attribute?schema=openid', [
	            'headers' => [
	                'Authorization' => 'Bearer '.$token['access_token'],
	            ],
	        ]);
	        return json_decode($response->getBody(), true);
	    }

	    //Userにパラメーターをマップ(必要に応じてその他のパラメータ追加)
	    protected function mapUserToObject(array $user)
	    {
	        return (new User())->setRaw($user)->map([
	            'id' => $user['user_id'],
	            'name' => $user['name'],
	            'email' => $user['email'],
	        ]);
	    }

	    //token parse用の関数
	    protected function parseAccessToken($body)
	    {
	        return json_decode($body, true);
	    }

	}

本質的な機能の実装はとりあえずこんな感じ。
ここで、Yahooデベロッパーネットワークにて取得・設定した情報を.envに追加しておきます。

#YahooJp
YahooJp_ID=アプリケーションID
YahooJp_SECRET=シークレット
YahooJp_CALLBACKURL=http://localhost:8000/yahoojp/callback(コールバックURL)

あとは、config/services.phpに.envパラメータとのmapを記述しておきます。

    'yahoojp' => [
        'client_id'     => env('YahooJp_ID'),
        'client_secret' => env('YahooJp_SECRET'),
        'redirect'      => env('YahooJp_CALLBACKURL'),
    ],

ここまでで主要機能の実装は完了です。

##初期化およびプロバイダのコンテナへの登録

ちょっと悩んだのが、機能を使えるようにする方法です。providerのAuthServiceProviderのbootに書くこともできるようですが、ここでは別途プロバイダクラスを用意し、サービスプロバイダに登録することにしました。

###MySocialManager

まずは、登録するクラスを用意します。

Laravel\Socialite\SocialiteManagerを継承して、yahoojpドライバの生成を記述します。
config/services.phpから必要な情報を読み込み初期化します。

MySocialManager.php

<?php

	namespace App\Socialite;

	use Laravel\Socialite\SocialiteManager;

	class MySocialManager extends SocialiteManager{

		protected function createYahooJpDriver()
		{
			//services.phpの設定情報を読む
			$config = $this->config['services.yahoojp'];
			//設定情報と共にプロバイダを生成
			return $this->buildProvider(
				'App\Socialite\YahooJpProvider',$config
			);
		}
	
	}

###MySocialServiceProvider

次にプロバイダクラスを用意します。
Laravel\Socialite\SocialiteServiceProviderを継承します。

MySocialServiceProvider.php

<?php
	
	namespace App\Socialite;

	use Laravel\Socialite\SocialiteServiceProvider;

	class MySocialServiceProvider extends SocialiteServiceProvider
	{
		public function register()
		{
			//シングルトンとしてMySocialManagerを生成
			$this->app->singleton('Laravel\Socialite\Contracts\Factory',function($app){
				return new MySocialManager($app);
			});
		}
	}

###config/app.phpの編集

登録するクラスの準備ができたので、'providers' => []中にプロバイダを追加します(一部抜粋)。

App\Socialite\MySocialServiceProvider::class,

これで利用できるようになりました。

##利用してみる

では、最低限の機能チェックをしてみます。

###Route設定

ソーシャルログインボタンのクリック先となるリダイレクト用ルートと認証後、戻ってくる先(Callback)用のルートを設定します。

Route::group(['middleware' => 'web'], function () {

    //Yahooログイン(ボタンのリンク先)
    Route::get('yahoojp','YahooJpController@yahoojpLogin');
    //認証後の戻りURL
    Route::get('yahoojp/callback','YahooJpController@yahoojpCallback');

});

###Controller

コントローラーを実装します。
と入っても、ドライバさえきちんと動けば、Controller内での実装は難しくはありません。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;

//追加
use Laravel\Socialite\Contracts\Factory as Socialite;

class YahooJpController extends Controller
{
    //
    protected $socialite;

    public function __construct(Socialite $socialite)
    {
    	$this->socialite = $socialite;
    }

    public function yahoojpLogin()
    {
    	//yahooへリダイレクト
    	return $this->socialite->driver('yahoojp')->redirect();
    }

    public function yahoojpCallback()
    {
    	//ユーザー情報を取得
    	$yuser = $this->socialite->driver('yahoojp')->user();

    	//各情報の取得
    	$yuser->getId();
    	$yuser->getName();
    	$yuser->getEmail();

    	//とりあえず表示
    	return $yuser->getEmail();
    }
}

以上です。emailが表示されればOKです。

出来てしまえば簡単ですが、試行錯誤が必要でした。

22
26
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?