LoginSignup
24
30

More than 5 years have passed since last update.

Laravel 5.3のSocialiteに含まれていないLINEやYahoo!JAPANなどの認証サービスを利用する方法

Last updated at Posted at 2016-10-11

やりたいこと

  • 表題の通り、laravel/socialiteで、twitterやfacebookのアカウント認証はできるようになったが、LINEやYahoo!JAPANのアカウントでも認証できるようにしたい。

前提

導入手順、の前に

導入手順

  • 基本的に、以下の流れで実装する。
  • 認証に使用するサービスのAPI仕様やらを見ながら、Providerをその仕様に合わせてガリガリ書いていけば、大体のサービスにおいては以下の手順でいける。。。と思う。

認証に使用するサービスごとにProviderを作成する。

  • LINE用プロバイダ

    app/socialite/Two/LineProvider.php
    <?php
    
    namespace app\Socialite\Two;
    
    use Laravel\Socialite\Two\AbstractProvider;
    use Laravel\Socialite\Two\ProviderInterface;
    use Laravel\Socialite\Two\User;
    
    class LineProvider extends AbstractProvider implements ProviderInterface
    {
        protected function getAuthUrl($state)
        {
            return $this->buildAuthUrlFromBase('https://access.line.me/dialog/oauth/weblogin', $state);
        }
    
        protected function getTokenUrl()
        {
            return 'https://api.line.me/v1/oauth/accessToken';
        }
    
        protected function getUserByToken($token)
        {
            $response = $this->getHttpClient()->get('https://api.line.me/v1/profile', [
                'headers' => [
                    'X-Line-ChannelToken' => $token,
                ],
            ]);
    
            return json_decode($response->getBody(), true);
        }
    
        protected function mapUserToObject(array $user)
        {
            return (new User())->setRaw($user)->map([
                'id'     => $user['mid'],
                'name'   => $user['displayName'],
                'avatar' => $user['pictureUrl'],
            ]);
        }
    
        protected function getTokenFields($code)
        {
            return [
                'client_id'     => $this->clientId,
                'client_secret' => $this->clientSecret,
                'code'          => $code,
                'redirect_uri'  => $this->redirectUrl,
                'grant_type'    => 'authorization_code',
            ];
        }
    }
    
  • Yahoo!JAPAN用プロバイダ

    app/socialite/Two/YahooProvider.php
    <?php
    
    namespace app\Socialite\Two;
    
    use Laravel\Socialite\Two\AbstractProvider;
    use Laravel\Socialite\Two\ProviderInterface;
    use Laravel\Socialite\Two\User;
    
    use GuzzleHttp\ClientInterface;
    
    class YahooProvider extends AbstractProvider implements ProviderInterface
    {
        protected $scopeSeparator = ' ';
    
        protected $scopes = [
            'openid',
            'profile',
            'email',
        ];
    
        protected function getAuthUrl($state)
        {
            return $this->buildAuthUrlFromBase('https://auth.login.yahoo.co.jp/yconnect/v1/authorization', $state);
        }
    
        protected function getTokenUrl()
        {
            return 'https://auth.login.yahoo.co.jp/yconnect/v1/token';
        }
    
        protected function getUserByToken($token)
        {
            $response = $this->getHttpClient()->get('https://userinfo.yahooapis.jp/yconnect/v1/attribute?schema=openid', [
                'headers' => [
                    'Authorization' => 'Bearer '.$token,
                ],
            ]);
    
            return json_decode($response->getBody(), true);
        }
    
        protected function mapUserToObject(array $user)
        {
            return (new User())->setRaw($user)->map([
                'id'         => $user['user_id'],
                'name'       => $user['name'],
                'email'      => $user['email'],
                'birth_year' => $user['birthday'],
                'gender'     => $user['gender'],
            ]);
        }
    
        /**
         * Basic認証が必要なのでOverWriteする。
         * @param string $code
         * @return mixed
         */
        public function getAccessTokenResponse($code)
        {
            $postKey = (version_compare(ClientInterface::VERSION, '6') === 1) ? 'form_params' : 'body';
    
            $basic_auth_key = base64_encode($this->clientId.":".$this->clientSecret);
    
            $response = $this->getHttpClient()->post($this->getTokenUrl(), [
                'headers' => [
                    'Authorization' => 'Basic '.$basic_auth_key,
                    'Content-Type'  => 'application/x-www-form-urlencoded',
                ],
                $postKey  => $this->getTokenFields($code),
            ]);
    
            return json_decode($response->getBody(), true);
        }
    
        /**
         * TokenFieldsに過不足があるのでOverWriteする。
         * :Basic認証のため不要
         *    - client_id
         *    - client_secret
         * :必須項目追加
         *    + grant_type
         * @param string $code
         * @return array
         */
        protected function getTokenFields($code)
        {
            return [
                'code'         => $code,
                'redirect_uri' => $this->redirectUrl,
                'grant_type'   => 'authorization_code',
            ];
        }
    }
    

SocialiteManager、SocialiteServiceProviderクラスを作成する。

  • Laravel\Socialite\SocialiteManagerクラスを継承して、作成したプロバイダを読み込むSocialiteManagerクラスを実装する

    app/socialite/SocialiteManager.php
    <?php
    
    namespace app\Socialite;
    
    class SocialiteManager extends \Laravel\Socialite\SocialiteManager
    {
        protected function createYahooDriver()
        {
            $config = $this->app['config']['services.yahoo'];
    
            return $this->buildProvider('app\Socialite\Two\YahooProvider', $config);
        }
    
        protected function createLineDriver()
        {
            $config = $this->app['config']['services.line'];
    
            return $this->buildProvider('app\Socialite\Two\LineProvider', $config);
        }
    }
    
  • Laravel\Socialite\SocialiteServiceProviderを継承して、作成したSocialiteManagerを呼び出すためのサービスプロバイダクラスを実装する。

    app/socialite/SocialiteServiceProvider.php
    <?php
    
    namespace app\Socialite;
    
    class SocialiteServiceProvider extends \Laravel\Socialite\SocialiteServiceProvider
    {
        public function register()
        {
            $this->app->singleton('Laravel\Socialite\Contracts\Factory', function ($app)
            {
                return new SocialiteManager($app);
            });
        }
    }
    

設定変更

  • SocialiteServiceProviderの向き先を、上記で作成したものに変える

    app/config/config.php
    <?php
    
    return [
    
        // ...
    
        'providers'       => [
    
            // ...
    
            //Laravel\Socialite\SocialiteServiceProvider::class,    //除外
            app\Socialite\SocialiteServiceProvider::class,          //追加
    
            // ...
    
        ],
    
        // ...
    
    ];
    
    
  • config/services.phpを編集する。

    config/services.php
    <?php
    
    return [
    
        // ...
    
        'line'   => [
            'client_id'     => env('LINE_CLIENT_ID'),
            'client_secret' => env('LINE_CLIENT_SECRET'),
            'redirect'      => env('LINE_REDIRECT'),
        ],
        'yahoo'  => [
            'client_id'     => env('YAHOO_CLIENT_ID'),
            'client_secret' => env('YAHOO_CLIENT_SECRET'),
            'redirect'      => env('YAHOO_REDIRECT'),
        ],
    
        // ...
    
    ];
    
    
  • .env.xxxxxを編集

    env.xxxxx
    # ...
    
    LINE_CLIENT_ID=(your-line-client-id)
    LINE_CLIENT_SECRET=(your-line-client-secret)
    LINE_REDIRECT=(your-line-redirect-url)
    
    YAHOO_CLIENT_ID=(your-yahoo-client-id)
    YAHOO_CLIENT_SECRET=(your-yahoo-client-secret)
    YAHOO_REDIRECT=(your-yahoo-redirect-url)
    
    # ...
    

認証実行

24
30
0

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
24
30