Laravel/Socialite: Class Laravel\Socialite\Contracts\Factory does not exist

若如初见. 提交于 2019-12-11 02:25:27

问题


I'm trying to implement socialite but I am getting an error relating to the Factory class. My app can not find it.

This is the code in my controller:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;

use Laravel\Socialite\Contracts\Factory as Socialite;

class PortalController extends Controller
{

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


    public function getSocialAuth($provider=null)
    {
       if(!config("services.$provider")) abort('404'); //just to handle providers that doesn't exist

       return $this->socialite->with($provider)->redirect();
    }


    public function getSocialAuthCallback($provider=null)
    {
       if($user = $this->socialite->with($provider)->user()){
          dd($user);
       }else{
          return 'something went wrong';
       }
    }

I added:

Laravel\Socialite\SocialiteServiceProvider::class, to providers and

'Socialite' => Laravel\Socialite\Facades\Socialite::class to aliases

and my routes looks like

Route::get('/portal/{provider?}',[
        'uses' => 'PortalController@getSocialAuth',
        'as'   => 'portal.getSocialAuth'
    ]);


    Route::get('/portal/callback/{provider?}',[
        'uses' => 'PortalController@getSocialAuthCallback',
        'as'   => 'portal.getSocialAuthCallback'
    ]);

The error I receive is:

ReflectionException in Container.php line 798: Class Laravel\Socialite\Contracts\Factory does not exist


回答1:


I also came across this issue in Laravel 5.5 while creating custom oAuth provider. After Long research I achieved by creating custom MySocialServiceProvider class whcih is need to extend by Laravel\Socialite\SocialiteServiceProvider. Please go through all the following code and setup with appropriate config, surely it will work.

My Directory structure as following in the image

MySocialServiceProvider.php

<?php

namespace App\Providers;

use Laravel\Socialite\SocialiteServiceProvider;

class MySocialServiceProvider extends SocialiteServiceProvider
{
    public function register()
    {
        $this->app->bind('Laravel\Socialite\Contracts\Factory', function ($app) {
            return new MySocialManager($app);
        });
    }
}

We have to create a Manger class which will contain as follows

MySocialManager.php

<?php

namespace App\Providers;

use App\Auth\SocialiteFooDriver;
use Laravel\Socialite\SocialiteManager;

class MySocialManager extends SocialiteManager
{
    protected function createFooDriver()
    {
        $config = $this->app['config']['services.foo'];

        return $this->buildProvider(
            SocialiteFooDriver::class, $config
        );
    }
}

We should create a Custom Driver which used by MySocialManger

SocialiteFooDriver.php

<?php

namespace App\Auth;

use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Laravel\Socialite\Two\AbstractProvider;
use Laravel\Socialite\Two\ProviderInterface;
use Laravel\Socialite\Two\User;

class SocialiteFooDriver extends AbstractProvider implements ProviderInterface
{
    /**
     * Foo API endpoint.
     *
     * @var string
     */
//    protected $apiUrl = 'https://auth.foobar.com';
    protected $apiUrl = '';

    public function __construct(Request $request, $clientId, $clientSecret, $redirectUrl)
    {
        parent::__construct($request, $clientId, $clientSecret, $redirectUrl);
        $this->apiUrl = config('services.foo.url');
    }

    /**
     * The scopes being requested.
     *
     * @var array
     */
    protected $scopes = ['openid email profile user_role user_full_name'];

    /**
     * {@inheritdoc}
     */
    protected function getAuthUrl($state)
    {
        return $this->buildAuthUrlFromBase($this->apiUrl.'/oauth2/authorize', $state);
    }

    /**
     * {@inheritdoc}
     */
    protected function getTokenUrl()
    {
        return $this->apiUrl.'/oauth2/token';
    }

    /**
     * {@inheritdoc}
     */
    protected function getUserByToken($token)
    {
        $userUrl = $this->apiUrl.'/oauth2/UserInfo?access_token='.$token;

        $response = $this->getHttpClient()->get(
            $userUrl, $this->getRequestOptions()
        );

        $user = json_decode($response->getBody(), true);

        if (in_array('user:email', $this->scopes)) {
            $user['email'] = $this->getEmailByToken($token);
        }

        return $user;
    }

    /**
     * Get the POST fields for the token request.
     *
     * @param string $code
     *
     * @return array
     */
    protected function getTokenFields($code)
    {
        return array_add(
            parent::getTokenFields($code), 'grant_type', 'authorization_code'
        );
    }

    /**
     * {@inheritdoc}
     */
    protected function mapUserToObject(array $user)
    {
        return (new User())->setRaw($user)->map([
            'id' => $user['sub'],
            'nickname' => $user['preferred_username'],
            'name' => Arr::get($user, 'name'),
            'email' => Arr::get($user, 'email'),
            'avatar' => $user['avatar'],               

        ]);
    }

    /**
     * Get the default options for an HTTP request.
     *
     * @return array
     */
    protected function getRequestOptions()
    {
        return [
            'headers' => [
                //'Accept' => 'application/vnd.github.v3+json',
            ],
        ];
    }
}

Finally we should have add config values in config/services.php

'foo' => [
        'client_id' => 'XXXXXXXX',
        'client_secret' => 'YYYYYYYY',
        'redirect' => 'http://example.com/login/foo/callback/',
        'url' => 'https://auth.foobar.com',
    ],

Dont forget to update config/app.php with our new provider

'providers' => [
//...

 \App\Providers\MySocialServiceProvider::class

]



回答2:


Official installation guide says you need to use this:

use Socialite;

Instead of:

use Laravel\Socialite\Contracts\Factory as Socialite;

If it's not working, try to use:

use Laravel\Socialite\Facades\Socialite

And then use composer dumpauto.




回答3:


From the doc, after adding Socialite library and facade to the respective providers and aliases array in config/app.php file, you just need to use Socialite as

use Socialite;

But you are using

use Laravel\Socialite\Contracts\Factory as Socialite;

So, just remove above line with

use Socialite;

updated from comment

composer update

and

composer dump-autoload

It should work.




回答4:


"composer update" fixed this issue for me and it works with: "use Laravel\Socialite\Contracts\Factory as Socialite;"



来源:https://stackoverflow.com/questions/36182601/laravel-socialite-class-laravel-socialite-contracts-factory-does-not-exist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!