SocialProvider

socialiteproviders ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

socialite๋ฅผ ์ด์šฉํ•˜์—ฌ ์ปค์Šคํ…€ provider๋ฅผ ๋งŒ๋“ค์–ด ์ ์šฉํ•˜๋ ค๊ณ  ํ• ๋•Œ ๊ทธ๋ƒฅ ์ ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋ณต์žกํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ socialiteproviders/manager๋ผ๋Š” ๋ฒค๋”๋ฅผ ์ด์šฉํ•˜๋ฉด ์ปค์Šคํ…€์ ์šฉ์ด ์‰ฝ๊ฒŒ ๊ฐ€๋Šฅํ•˜๋‹ค.

ํ™•์‹คํ•œ ๊ตฌ์กฐ๋ฅผ ์•Œ๊ณ ์‹ถ๋‹ค๋ฉด socialiteproviders/naver์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์„œ๋น„์Šค์˜ oauth ๋ฒค๋”๋ฅผ ๋‹ค์šด๋ฐ›์•„ ๋œฏ์–ด๋ณด๋ฉด ๋˜๊ณ  ํ˜„์žฌ ์ž‘์„ฑํ•˜๋Š” ๊ธ€๋„ ๋‹ค๋ฅธ ์„œ๋น„์Šค์˜ ๊ตฌ์กฐ๋ฅผ ๋œฏ์–ด ๋น„์Šทํ•˜๊ฒŒ ์ ์šฉํ•œ ์‚ฌ๋ก€์ด๋‹ค.

์šฐ์„  socialiteproviders/manager๋ฅผ ์„ค์น˜ํ•ด์ฃผ๋ฉด๋œ๋‹ค.

1. ํ™˜๊ฒฝ ์„ค์ • ํ•ด์ฃผ๊ธฐ

//config/services.php
return [

    //...

'saramin' => [
        'client_id' => env('SARAMIN_ID'),
        'client_secret' => env('SARAMIN_SECRET'),
        'redirect' => env('SARAMIN_CALLBACK'),
    ],

    //...
];

//config/app.php
'providers' => [
    //...
    \SocialiteProviders\Manager\ServiceProvider::class,
],

'aliases' => [
    //...
    'Socialite' => Laravel\Socialite\Facades\Socialite::class,
]

์œ„์™€ ๊ฐ™์ด services.php์™€ app.php์— ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ  .env์— ๊ฐ€์„œ services.php์˜ 3๊ฐœ์˜ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ์ •๋ณด๋ฅผ ๊ธฐ์ž…ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

2. Provider ์ถ”๊ฐ€

class SaraminProvider extends AbstractProvider
{

    public const IDENTIFIER = 'SARAMIN';
    private const OAUTH_URL = 'url';
    private const GATEWAY_URL = 'url';

    protected $scopes = [
        "openid",
        "scopes",
        //...
    ];

    protected $scopeSeparator = ' ';

    /**
     * {@inheritdoc}
     */
    protected function getAuthUrl($state): string
    {
        return $this->buildAuthUrlFromBase(
            self::OAUTH_URL . '/oauth/authorize',
            $state
        );
    }

    /**
     * {@inheritdoc}
     */
    protected function getTokenUrl(): string
    {
        return self::OAUTH_URL . '/oauth/token';
    }

    /**
     * {@inheritdoc}
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    protected function getUserByToken($token)
    {
        $response = $this->getHttpClient()->get(
            self::GATEWAY_URL . '/api/user/oauth/user',
            [
                'headers' => [
                    'Accept' => 'application/json',
                    'Authorization' => 'Bearer ' . $token,
                ],
            ]);
        return json_decode($response->getBody(), true);
    }

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

3. ProviderManager ์ƒ์„ฑ

class SaraminExtendSocialite
{
    public function handle(SocialiteWasCalled $socialiteWasCalled)
    {
        $socialiteWasCalled->extendSocialite('saramin', \App\Oauth\SaraminProvider::class);
    }
}

saramin์˜ socialite๊ฐ€ ๋ถˆ๋ ธ์„๋•Œ ์ƒ์„ฑํ•œ Provider๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก Provider๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

4. EventServiceProvider์˜ listen์— ProviderManager ์ถ”๊ฐ€

//...
protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        \SocialiteProviders\Manager\SocialiteWasCalled::class => [
            'App\Oauth\SaraminExtendSocialite@handle',
        ],
    ];

5. Controller ์ƒ์„ฑ

class SocialController extends Controller
{

    /**
     * Handle social login process.
     *
     * @param Request $request
     * @param string $provider
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
     */
   public function execute(Request $request, string $provider){
       //์ธ์ฆ์„œ๋ฒ„๋กœ redirect
        if (! $request->has('code')){
            return $this->redirectToProvider($provider);
        }

        //token์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด token์„œ๋ฒ„๋กœ redirect
       return $this->handleProviderCallback($provider);
   }

    /**
     * Redirect the user to the Social Login Provider's authentication page.
     *
     * @param string $provider
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
     * @throws BadRequestException
     */
   protected function redirectToProvider(string $provider): \Symfony\Component\HttpFoundation\RedirectResponse
   {
       switch ($provider){
           case 'saramin' :
               return Socialite::driver($provider)
                   ->redirect();
           default:
               throw new BadRequestException("์ž˜๋ชป๋œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค.");
       }
   }

    /**
     * Obtain the user information from the Social Login Provider.
     *
     * @param string $provider
     * @return Application|Redirector|RedirectResponse
     * @throws UnauthorizeException
     * @throws InternalServerException
     */
   protected function handleProviderCallback(string $provider){
       $socialData = Socialite::driver($provider)->user();

      //์ธ์ฆ ๋กœ์ง...

       return redirect('/success');
   }
}

์œ„์™€ ๊ฐ™์ด Controller๊นŒ์ง€ ์ƒ์„ฑํ•ด์ค€ํ›„ web.php์— ๋ผ์šฐํ„ฐ๋งŒ ๋“ฑ๋ก์„ ์‹œ์ผœ์ฃผ๋ฉด ์ ์šฉ์ด ๋œ๋‹ค!!

Socialiteproviders๊ฐ€ ์•„๋‹Œ Socialite๋งŒ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•

1. ์„ค์ •ํŒŒ์ผ๊ณผ Provider ์ƒ์„ฑ

์ฒซ๋ฒˆ์งธ์˜ ๋ฐฉ๋ฒ•๊ณผ ๊ฑฐ์˜ ๋™์ผํ•˜๋‚˜ app.php์—์„œ providers์˜ ์ •๋ณด๋งŒ ์ˆ˜์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

//์ˆ˜์ • ์ „
\SocialiteProviders\Manager\ServiceProvider::class,

//์ˆ˜์ • ํ›„
Laravel\Socialite\SocialiteServiceProvider::class,

2. AppServiceProvider์— ์‚ฌ๋žŒ์ธProvider ๋“ฑ๋ก

//AppserviceProvider ํด๋ž˜์Šค ๋‚ด๋ถ€
public function boot(){
    $socialite = $this->app->make('Laravel\Socialite\Contracts\Factory');
        $socialite->extend(
            'saramin',
            function ($app) use ($socialite) {
                $config = $app['config']['services.saramin'];
                return $socialite->buildProvider(SaraminProvider::class, $config);
            }
        );
}

boot()๋ฉ”์„œ๋“œ๋Š” ๋‹ค๋ฅธ ์„œ๋น„์Šค ํ”„๋กœ๋ฐ”์ด๋”๋“ค์ด ๋“ฑ๋ก๋œ ์ดํ›„์— ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์— Socialite์— ์œ„์™€ ๊ฐ™์ด ์ ‘๊ทผํ•˜์—ฌ Provider๋ฅผ ์ถ”๊ฐ€ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

Last updated