서론
로그인 구현 방식에는 여러가지 방식이 있지만, 요즘에는 Oauth 방식을 이용한 로그인 방식이 많이 사용 됩니다.
라라벨에서는 passport라는 인증 관련 확장 프로그램을 제공해 주어, 쉽게 Oauth 방식 로그인구현이 가능합니다.
하지만 한글로 된 문서는 거의 없어서 처음 접해보시는 분들은 구현하기 힘들어 하시는 분들도 많으실 텐데,
정리해보면서 풀어나가 보려고 합니다!
기본적으로, DB와 Laravel은 먼저 연동이 되어 있다고 가정 하에 설명 드리도록 하겠습니다.
laravel/passport 세팅
먼저, composer를 이용하여 laravel/passport를 설치 해 봅시다.
composer require laravel/passport
그 다음으로는 유저 정보가 있어야지만 테스트가 가능하겠죠?
기본적으로 라라벨을 처음 설치하고 나면 /database/migrations 폴더 하위에 create_users_table 이라는 파일이 하나 존재합니다.
php artisan migrate를 이미 실행 하신 분들은,
composer require doctrine/dbal
위 확장프로그램을 설치해 주시고,
php artisan make:migration [migration_name] --table=users
위와 같은 명령어를 사용하여 users 테이블을 수정할 내용을 작업해 주도록 합시다.
php artisan migrate를 아직 실행하지 않으신 분들은 up() 메소드 안쪽을 수정하여 내가 원하는 유저 테이블을 만들어 주도록 합시다.
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('user_no')->comment("회원 번호");
$table->string("user_id",100)->comment("유저 아이디")->unique();
$table->string("password",100)->comment("유저 비밀번호");
$table->string("phone_number",20)->nullable()->comment("유저 핸드폰 번호");
$table->string("user_name",50)->nullable()->comment("유저 이름");
$table->char("user_gender",1)->nullable()->comment("유저 성별. M: 남자, F: 여자");
$table->string("kakao_id", 100)->nullable()->comment("카카오 API 회원 가입 id");
$table->string("kakao_token", 100)->nullable()->comment("카카오 API 회원 가입 토큰");
$table->string("naver_id", 100)->nullable()->comment("네이버 API 회원가입 id");
$table->string("naver_token", 100)->nullable()->comment("네이버 API 회원가입 토큰");
$table->integer("now_point")->default(0)->comment("현재 유저 포인트");
$table->integer("now_reward")->default(0)->comment("현재 유저 리워드");
$table->integer("total_reward")->default(0)->comment("토탈 유저 리워드");
$table->integer("follower_count")->default(0)->comment("팔로우한 유저 수");
$table->integer("win_count")->default(0)->comment("우승 회수");
$table->char("receive_push")->default(1)->comment("모든 푸시 수신 여부, 0: 미수신, 1: 수신");
$table->char("is_active")->default(0)->comment("유저 정지 여부, 0: 정지, 1: 미정지");
$table->dateTime("stop_start_at")->nullable()->comment("유저 정지 시작 시간");
$table->dateTime("stop_end_at")->nullable()->comment("유저 정지 종료 시간");
$table->dateTime("last_login_at")->nullable()->comment("최종 로그인 시각");
$table->string("device_token", 100)->nullable()->comment("핸드폰 디바이스 토큰 값");
$table->char("device_type", 1)->nullable()->comment("디바이스 종류. 1: Android, 2: IOS, 3: Other");
$table->integer("user_level")->default(1)->comment("유저 레벨 1:기본 10:관리자");
$table->softDeletes();
$table->timestamps();
});
}
저는 위와 같이 생성했지만, 원하시는대로 작업해 주시면 됩니다.
한가지 유의해야 할 점은, 기존에는 유저 id값이 email로 처리가 되었다는 점 입니다.
일단 유저 테이블을 수정 해 주셨으면
php artisan migrate
를 실행하여 유저테이블을 생성하면서, passport 설치시에 같이 migrate 파일이 생성된 여러 테이블들도 같이 생성해 주도록 합니다.
이제 테스트할 데이터베이스도 만들었으니, Oauth 인증을 위한 추가적인 세팅을 진행하겠습니다.
php artisan passport:install
위 명령어를 실행해 줍니다.
이후 storage 폴더 하위를 확인해 보시면 oauth-private.key, oauth-public.key 두개의 파일이 생성됨을 확인 하실 수 있습니다.
그 후, config/auth.php 파일 안의 guards 부분을 다음과 같이 수정해 줍니다.
api 부분의 driver를 passport로 변경해 주었습니다.
테스트 진행을 위한 프로그래밍
먼저, User Model을 본인이 설정한 DB 스킴대로 편집을 진행해 줍니다.
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
use DateTimeInterface;
class User extends Authenticatable
{
use HasFactory, Notifiable, HasApiTokens;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $table = 'users';
protected $primaryKey = "user_no";
protected $fillable = [
'user_id',
'password',
'phone_number',
'user_name',
'user_gender',
'user_nickname',
'kakao_id',
'kakao_token',
'naver_id',
'naver_token',
'is_active',
'stop_start_at',
'stop_end_at',
'device_token',
'user_level',
'device_type'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password'
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
// 'email_verified_at' => 'datetime',
// 'created_at' => "datetime:Y-m-d H:m:s",
// 'updated_at' => "datetime:Y-m-d H:m:s",
];
public function findForPassport($userId) {
return $this->where('user_id', $userId)->first();
}
/**
* Prepare a date for array / JSON serialization.
*
* @param \DateTimeInterface $date
* @return string
*/
protected function getAttributeCreatedAT(DateTimeInterface $date)
{
return $date->format('Y-m-d H:i:s');
}
}
여기서 중요시 봐야할 부분은 findForPassport 부분입니다.
라라벨 최초 설치시 email을 id값으로 설정되어 있기 때문에, 해당 부분을 스키마에서 변경하신 분은 꼭 추가하여 수정해 주도록 합시다.
저는 email 대신 user_id 값을 id 필드로 지정하여서, 위와같이 추가하였습니다.
그 후, 컨트롤러를 하나 생성하여 토큰을 생성, 갱신하는 함수들을 만들어 봅시다.
php artisan make:controller Auth/ApiAuthController
public function generateAccessToken($authData) {
$request = Request::create('/oauth/token', 'POST', $authData);
try {
$response = app()->handle($request);
if($response->getStatusCode() == 200) {
LoginProcessed::dispatch($user);
$auth_info = json_decode($response->content(), true);
return $auth_info;
} else {
$response = json_decode($response->content(), true);
return response($response, 422);
}
} catch (\Exception $e) {
return response($response, 500);
}
}
public function createToken(Request $request) {
$user = User::where('user_id', $request->user_id)->first();
if($user) {
$data = [
'grant_type'=>'password',
'client_id' => env("APP_CLIENT_ID"),
'client_secret'=> env("APP_CLIENT_SECRET"), // oauth_clients id = 2의 secret 값
'username'=>$user->user_id,
'password'=>$request->password,
'scope'=>'*'
];
return $this->generateAccessToken($data);
} else {
$response = ["message" => "user is not found"];
return response($response, 422);
}
}
public function tokenRefresh(Request $request) {
$data = [
'grant_type' => "refresh_token",
'refresh_token' => $request->headers->get('refresh_token'),
'client_id' => env("APP_CLIENT_ID"),
'client_secret'=> env("APP_CLIENT_SECRET"), // oauth_clients id = 2의 secret 값
'scope' => '',
];
$request = Request::create('/oauth/token', 'POST', $data);
$response = app()->handle($request);
$response = json_decode($response->content(),true);
try {
if(isset($response['error'])) {
return response($response, 401);
} else {
return response($response, 200);
}
} catch (\Exception $e) {
return response($response, 500);
}
}
위 내용을 생성한 컨트롤러에 넣어 줍니다.
env 파일에는 oauth_clients 테이블 에서 확인 가능한 값인 APP_CLIENT_ID와 APP_CLIENT_SECRET값을 넣어서 세팅해 주도록 합니다.
그 후, UserController에서 간단한 회원가입 API를 만들어 주시고, 회원가입을 진행시켜 주세요.
회원가입 진행 이후 UserController에 login API를 만들어 줍시다.
public function login(Request $request) {
$apiAuthController = new ApiAuthController();
return $apiAuthController->createToken($request);
}
라우팅 파일을 수정하여 로그인 메소드에 연결해 줍니다.
단 이때, api.php 파일에서 미들웨어api 바깥쪽에 설정해 주도록 해 주세요.
이후, 생성한 유저로 로그인 시 위와같이 만료일자, access_token, refresh_token등이 발급 되게 됩니다.
그 다음 간단한 api를 만들어, 해당 토큰값으로 인증이 이루어지는지 확인해 보도록 합니다.
그 후, 포스트맨 등으로 위 api와 통신을 시켜보면,
{
"message": "Unauthenticated."
}
라는 내용을 확인할 수 있습니다.
하지만 헤더 값에
Accept : application/json
Authorization: Bearer {{access_token}} 값을 넣어 주시면 성공적으로 success가 반환됨을 확인 하실 수 있습니다!
※ 여기서 {{access_token}} 값은 위 login api에서 반환된 access_token 값을 넣어 주셔야 됩니다.
refersh_token은 위에서 작성한 코드를 보고 직접 한번 연동해 보세요~!
'PHP > PHP' 카테고리의 다른 글
Laravel Sanctum과 Passport 차이, Passport의 인증방식들 정리 (0) | 2023.04.05 |
---|---|
Laravel, Laravel Octane 그냥 공부 메모.. (0) | 2023.04.04 |
[Laravel] Laravel + Vue 연동 (0) | 2020.12.15 |
[Laravel] AWS S3 연동하기 및 파일 업로드 구현 (0) | 2019.12.11 |
[PHP Mailer] PHP 메일 발송하기 (0) | 2019.11.27 |