2020-05-13
laravel에서는 facebook, twitter, linkedin, google, github, gitlab, bitbucket의 소셜 로그인을 기본적으로 지원한다.
공식메뉴얼: https://laravel.kr/docs/6.x/socialite

그리고 오늘 포스팅할 google OAuth 인증은 아래 링크를 참고 하면 된다.
링크: https://www.itsolutionstuff.com/post/laravel-58-login-with-google-account-exampleexample.html


우선 해당 기능을 사용하기 위해서는 laravel 인증이 적용되어 있어야 한다.
링크: https://laravel.kr/docs/6.x/authentication

그리고 google OAuth에 필요한 key와 secret번호는 아래 링크로 가서 발급 받아야 한다.
링크: https://console.cloud.google.com/apis/credentials
해당 링크로 가서, OAuth 2.0 클라이언트 ID를 새로 하나 발급 받으면 된다.
키와 보안 비밀번호 발급은, 정식 도메인만 있으면, 등록하는데 크게 문제 될 것이 없을 것이다.
설정시에 "승인된 리디렉션 URI"에 "https://도메인/auth/google/callback"식으로만 잘 등록 해놓으면, 된다.

그럼 본격적으로 해야할 일은 아래와 같다.

socialite 설치
$ composer require laravel/socialite

config/app.php
- 공급자와 별칭 추가
'providers' => [
	....
	Laravel\Socialite\SocialiteServiceProvider::class,
],

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

config/services.php
- google id, secret 설정
- .env파일에서 GOOGLE_CLIENT_ID와 GOOGLE_CLIENT_SECRET를 등록해서 사용한다.
'google' => [
	'client_id' => env('GOOGLE_CLIENT_ID'),
	'client_secret' => env('GOOGLE_CLIENT_SECRET'),
	'redirect' => 'http://도메인/auth/google/callback',
],

migration 추가
- google id를 저장할 컬럼을 users 테이블에 추가한다
$ php artisan make:migration add_google_id_column

database/migrations/2020_05_12_025748_add_google_id_column.php
- 파일명은 만든 시기에 따라서 조금 다르게 됨
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddGoogleIdColumn extends Migration
{
	public function up()
	{
		//추가
		Schema::table('users', function ($table) {
			$table->string('google_id')->nullable();
		});
	}
.
.
.

app/User.php
- $fillable 에 'google_id' 추가
namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
	use Notifiable;

	protected $fillable = [
		'name', 'email', 'password', 'google_id'
	];
.
.
.

routes/web.php
- OAuth 주소로 사용될 route 등록
Route::get('auth/google', 'Auth\LoginController@redirectToProvider');
Route::get('auth/google/callback', 'Auth\LoginController@handleProviderCallback');

app/Http/Controllers/Auth/LoginController.php
- 실제로 로그인이 이루어지는 부분이다.
- 최초로그인 시에는 간단히 계정을 생성해주고, 기존 사용자일 경우는 대조후에 로그인 시켜준다
namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

use Socialite;
use Auth;
use Exception;
use App\User;

class LoginController extends Controller
{
	.
	.
	.

	public function redirectToProvider()
	{
		return Socialite::driver('google')->redirect();
	}

	public function handleProviderCallback()
	{
		// try {

			$user = Socialite::driver('google')->user();

			$finduser = User::where('google_id', $user->id)->first();

			if($finduser){

				Auth::login($finduser);

				return redirect('/home');

			}else{
				$newUser = User::create([
					'name' => $user->name,
					'email' => $user->email,
					'google_id'=> $user->id,
					'password'=> bcrypt('123123123')
				]);

				Auth::login($newUser);

				return redirect('/home');
			}

		// } catch (Exception $e) {
		// 	return redirect('/auth/google');
		// }
	}

}
위 부분에서 주의할 것이 몇가지 있는데,
1. try~catch 부분은 주석처리를 해두었다. 테스트 과정에서는 try부분을 없어야 에러 문구를 쉽게 확인 할 수 있기 때문이다.
2. User::create부분에서 password를 임의로 설정했다. User테이블의 password가 not null로 설정 되어 있는게 기본이기 때문이다.
3. 위 부분에서 아래와 같은 에러가 발생 할수도 있다.
GuzzleHttp\Exception\RequestException cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)
위 에러는 curl 인증 관련 문제로 인해 발생 하는 것으로, 아래 사이트에서 carcet.pem 파일을 받고, php.ini파일에서 curl.cainfo 경로를 수정해 주면 된다.
링크: https://curl.haxx.se/docs/caextract.html

php.ini
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo = "C:\php7\extras\ssl\cacert.pem"

위부분에 실제로 /auth/google 링크가 포함된 view페이지는 예제에 포함시키지 않았는데, html페이지는 적당히 만들어서 링크만 걸어주면 되기 때문에 생략 했다.