개발 알다가도 모르겠네요

Laravel에서 Social OAuth 2.0 구현하기 본문

웹/Laravel

Laravel에서 Social OAuth 2.0 구현하기

이재빵 2023. 6. 1. 12:57
728x90

OAuth란?

사용자가 비밀번호를 제공하지 않고 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준.

 

구현 권장 방식

기본
네이티브 앱 서비스 
 
클라이언트에서 인가 코드 및 토큰 발급 모두 처리

Redirect 방식   

웹 서비스 클라이언트에서 소셜 로그인 요청 시, 인가 코드가 발급되어 서비스 서버의 Redirect URI로 전달됨.
서비스 서버에서 인가 코드로 토큰 발급을 요청해야 함.

 

REST API 시퀀스 다이어그램 (PC 및 모바일 웹 환경 권장)

 

네이티브 시퀀스

1. 클라이언트에서 SNS 서버로 로그인 요청

2. SNS 서버로부터 access token 받음

3. 서버에 access token 전달

4. 서버에서 전달받은 access token를 SNS 서버로부터 검증

5. SNS서버로부터 해당 유저 정보를 받음

 

 

카카오

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

kakao developers 애플리케이션 추가

1. 내 애플리케이션 -> 애플리케이션 추가하기

2.제품 설정 -> 카카오 로그인 -> '활성화 설정' ON.

3. Redirect URI 추가. (카카오 로그인에서 사용할 OAuth Redirect URI를 설정 / REST API로 개발하는 경우 필수로 설정)

4. 제품 설정 -> 보안 -> Client Secret '활성화 상태' 사용함.

 

client id : 앱 키 -> REST API 키

client secret : 제품설정 -> 보안 -> 코드

redirect uri : 제품 설정 -> 카카오 로그인 -> Redirect URI

 

 

access token 생성법

1.인가 코드 받기

https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=0ff449b6dfbb2032d2af9a0b7a92e4a4&redirect_uri=http://localhost:8011/api/auth/login/social

Redicect되면서 redirect_uri로 code 반환함.

 

2.토큰 받기

https://kauth.kakao.com/oauth/token

"code" 에는 1번에서 받은 code를 넣으면 된다.

 

 

3. 사용자 정보 가져오기

https://kapi.kakao.com/v2/user/me

Headers -> Authorization에 2번에서 받은 access_token을 넣는다.

이런식으로 response가 오는데, 경우에 따라 추가적인 값들이 올 수 있다.

 

 

네이버

 

네이버 로그인 개발가이드 - LOGIN

네이버 로그인 개발가이드 1. 개요 4,200만 네이버 회원을 여러분의 사용자로! 네이버 회원이라면, 여러분의 사이트를 간편하게 이용할 수 있습니다. 전 국민 모두가 가지고 있는 네이버 아이디

developers.naver.com

 

Naver Developers에서 애플리케이션 등록

1. Application -> 애플리케이션 등록

2. API 설정 -> '네이버 로그인 Callback URL' 등록.

 

client id : 내 애플리케이션 -> 애플리케이션 정보 -> Client ID

client secret : 내 애플리케이션 -> 애플리케이션 정보 -> Client Secret

redirect uri : API 설정 -> 네이버 로그인 Callback URL

 

 

access token 생성법

1.인가 코드 받기

https://nid.naver.com/oauth2.0/authorize?client_id=tO7S16rhbsiBMPRRr5Tk&response_type=code&redirect_uri=http://127.0.0.1:9090/navercallback

Redicect되면서 redirect_uri로 code 반환함.

 

2.토큰 받기

https://nid.naver.com/oauth2.0/token?grant_type=authorization_code&client_id=tO7S16rhbsiBMPRRr5Tk&client_secret=4PmrJWi0rI&code=M9YMU6pcissr18v6lr

"code" 에는 1번에서 받은 code를 넣으면 된다.

 

3. 사용자 정보 가져오기

https://openapi.naver.com/v1/nid/me

Headers -> Authorization에 2번에서 받은 access_token을 넣는다.

이런식으로 response가 오는데, 경우에 따라 추가적인 값들이 올 수 있다.

 

 

 

구글

 

웹 서버 애플리케이션용 OAuth 2.0 사용  |  Authorization  |  Google for Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. Switch to English 의견 보내기 웹 서버 애플리케이션용 OAuth 2.0 사용 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분

developers.google.com

 

Google Cloud에서 애플리케이션 등록

1. API 및 서비스 -> 사용자 인증 정보 -> OAuth 2.0 클라이언트 ID 추가

2. 해당 OAuth 2.0 클라이언트 ID -> 승인된 리디렉션 URI 추가.

 

client id : 사용자 인증 정보 -> OAuth 2.0 클라이언트 ID -> Additional information -> 클라이언트 ID

client secret : 사용자 인증 정보 -> OAuth 2.0 클라이언트 ID -> Additional information -> 클라이언트 보안 비밀번호

redirect uri : 사용자 인증 정보 -> OAuth 2.0 클라이언트 ID -> 승인된 리디렉션 URI

 

 

access token 생성법

1.토큰 받기

아래의 사이트에서 인가코드 발급 ~ access token 발급 까지의 과정을 수행할 수 있다.

 

Get Access Token

 

fadi-asfour.github.io

 

2. 사용자 정보 가져오기

https://www.googleapis.com/oauth2/v2/userinfo

Headers -> Authorization에 2번에서 받은 access_token을 넣는다.

이런식으로 response가 오는데, 경우에 따라 추가적인 값들이 올 수 있다.

 

 

애플

 

Generate and validate tokens | Apple Developer Documentation

Validate an authorization grant code delivered to your app to obtain tokens, or validate an existing refresh token.

developer.apple.com

 

Apple Developer에서 Identifiers 등록

1. Add Services IDs

2. Identifier은 App ID Prefix(Team ID).com.domainname.appname

 

client id : Certificates, Identifiers & Profiles -> Bundle ID

client secret : 아래 참조.

redirect uri : Certificates, Identifiers & Profiles -> Capabilites -> Sign In with Apple -> Server-to-Server Notification Endpoint

 

Client Secret 발급

1. Certificates, Identifiers & Profiles -> Keys -> Register a New Key

2. Key ID 자동발급

3. p8 형식의 auth key 파일 자동발급

 

key_file : auth key 파일명

team_id : Certificates, Identifiers & Profiles -> Apple ID Prefix

client_id : Certificates, Identifiers & Profiles -> Bundle ID

key_id : Certificates, Identifiers & Profiles -> Keys -> View Key Details

 

 

아래의 코드를 실행하여 client secret을 발급받는다.

import jwt
import time
from ecdsa import SigningKey

key_file = 'AuthKey_DZ5GTFGK2H.p8'
team_id = 'SQ2T4G4BPD'
client_id = 'SQ2T4G4BPD.com.test1.test2'
key_id = 'DZ5GTFGK2H'

with open(key_file, 'r') as f:
    ecdsa_key = SigningKey.from_pem(f.read())

headers = {
  'kid': key_id
}

claims = {
  'iss': team_id,
  'iat': int(time.time()),
  'exp': int(time.time()) + 86400*180,
  'aud': 'https://appleid.apple.com',
  'sub': client_id
}

token = jwt.encode(claims, ecdsa_key.to_pem(), algorithm='ES256', headers=headers)

print(token)

 

access token 생성법

1.인가 코드 받기

https://appleid.apple.com/auth/authorize?response_type=code&client_id=SQ2T4G4BPD.com.okv.emo&redirect_uri=https://test.com

Redicect되면서 redirect_uri로 code 반환함.

2.토큰 받기

https://appleid.apple.com/auth/token

"code" 에는 1번에서 받은 code를 넣으면 된다.

 

 

3. 사용자 정보 가져오기

애플에서 따로 사용자 정보를 가져오는 rest api를 지원하지 않는 것으로 보인다.

따라서 laravel socialite provider로 구현한 api를 사용하였다.

 

이때 access token으로 response의 "access_token" 이 아닌 "id_token" 만 인식되었다.

즉 애플에서는 id_token이 access token 역할을 하는지에 대한 확인이 필요하다.


 

라라벨 코드에 적용하는 법

라라벨에서 제공하는 Socialite Providers 라이브러리를 사용.

 

Socialite Providers

Apple Installation & Basic Usage Please see the Base Installation Guide (opens new window), then follow the provider specific instructions below. Add configuration to config/services.php See Configure Apple ID Authentication (opens new window) Note: the cl

socialiteproviders.com

 

라이브러리 설치

composer require laravel/socialite --ignore-platform-reqs 

composer require socialiteproviders/manager --ignore-platform-reqs

composer require socialiteproviders/kakao --ignore-platform-reqs
composer require socialiteproviders/naver --ignore-platform-reqs
composer require socialiteproviders/google --ignore-platform-reqs
composer require socialiteproviders/apple --ignore-platform-reqs

 

config/services.php

	'kakao' => [
        'client_id' => env('KAKAO_CLIENT_ID'),
        'client_secret' => env('KAKAO_CLIENT_SECRET'),
        'redirect' => env('KAKAO_REDIRECT_URI'),
    ],

    'naver' => [
        'client_id' => env('NAVER_CLIENT_ID'),
        'client_secret' => env('NAVER_CLIENT_SECRET'),
        'redirect' => env('NAVER_REDIRECT_URI'),
    ],

    'google' => [
        'client_id' => env('GOOGLE_CLIENT_ID'),
        'client_secret' => env('GOOGLE_CLIENT_SECRET'),
        'redirect' => env('GOOGLE_REDIRECT_URI'),
    ],

    'apple' => [
        'client_id' => env('APPLE_CLIENT_ID'),
        'client_secret' => env('APPLE_CLIENT_SECRET'),
        'redirect' => env('APPLE_REDIRECT_URI'),
    ],

 

Providers/EventServiceProvider.php

  protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        \SocialiteProviders\Manager\SocialiteWasCalled::class => [
            'SocialiteProviders\\Kakao\\KakaoExtendSocialite@handle',
            'SocialiteProviders\\Naver\\NaverExtendSocialite@handle',
            'SocialiteProviders\\Google\\GoogleExtendSocialite@handle',
            'SocialiteProviders\\Apple\\AppleExtendSocialite@handle',
        ],
    ];

 

config/app.php

'providers' => [

       ...

        SocialiteProviders\Manager\ServiceProvider::class,

    ],

 

routes/api.php

Route::post('login/social', [AuthController::class, 'socialLogin']);

 

AuthController.php

	public function socialLogin(Request $request)
    {
        $this->validate($request, [
            'provider'    => ['required', 'string'],
            'access_token' => ['required', 'string']
        ]);

        $provider = $request->provider;
        $validated = $this->validateProvider($provider);
        if (!is_null($validated))
            return $validated;
        $providerUser = Socialite::driver($provider)->userFromToken($request->access_token);

        if (User::where('email', PetraCommon::encrypt($providerUser->getEmail()))->exists() || User::where('sns_email', PetraCommon::encrypt($providerUser->getEmail()))->exists()) {
            return response()->error(1001, 409);
        }

        $user = $providerUser->getRaw();
        return response()->success($user, 201);
    }
    
    
    protected function validateProvider($provider)
    {
        if (!in_array($provider, ['kakao', 'naver', 'google', 'apple'])) {
            return response()->json(["message" => 'You can only login via Kakao, Naver, Google, Apple account'], 400);
        }
    }

 

 

참고자료

 

🌐 OAuth 2.0 개념 - 그림으로 이해하기 쉽게 설명

OAuth란? 웹 서핑을 하다 보면 Google과 Facebook 등의 외부 소셜 계정을 기반으로 간편히 회원가입 및 로그인할 수 있는 웹 어플리케이션을 쉽게 찾아볼 수 있다. 클릭 한 번으로 간편하게 로그인할

inpa.tistory.com

 

' > Laravel' 카테고리의 다른 글

Laravel Controller  (1) 2023.03.15
Laravel Sail을 알아보자  (0) 2023.03.14
Laravel 파일 구조와 라우팅  (0) 2023.03.13
Windows에서 Laravel 도커 실행시 오류 문제 해결  (0) 2023.03.08