feat: MNG → DEV 자동 로그인 API 구현

- login_tokens 테이블 마이그레이션 생성
- LoginToken 모델 생성 (One-Time Token 관리)
- POST /api/v1/token-login 엔드포인트 추가
- 토큰 검증 후 access_token 발급, 1회용 토큰 삭제

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-20 13:43:04 +09:00
parent 993b347fb7
commit 7bea6f2deb
4 changed files with 174 additions and 0 deletions

View File

@@ -3,6 +3,7 @@
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use App\Models\LoginToken;
use App\Models\Members\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -110,4 +111,45 @@ public function signup(Request $request)
return ['user' => $user->only(['id', 'user_id', 'name', 'email', 'phone'])];
});
}
/**
* One-Time Token을 사용한 자동 로그인 (MNG → DEV)
*/
public function tokenLogin(Request $request)
{
$token = $request->input('token');
if (! $token) {
return response()->json(['error' => '토큰이 필요합니다.'], 400);
}
// 토큰 검증
$loginToken = LoginToken::findValidToken($token);
if (! $loginToken) {
return response()->json(['error' => '유효하지 않거나 만료된 토큰입니다.'], 401);
}
// 토큰 사용 (1회용 - 사용 후 삭제)
$user = $loginToken->consume();
// 액세스 + 리프레시 토큰 발급
$tokens = \App\Services\AuthService::issueTokens($user);
// 사용자 정보 조회 (테넌트 + 메뉴 포함)
$loginInfo = \App\Services\MemberService::getUserInfoForLogin($user->id);
return response()->json([
'message' => '로그인 성공',
'access_token' => $tokens['access_token'],
'refresh_token' => $tokens['refresh_token'],
'token_type' => $tokens['token_type'],
'expires_in' => $tokens['expires_in'],
'expires_at' => $tokens['expires_at'],
'user' => $loginInfo['user'],
'tenant' => $loginInfo['tenant'],
'menus' => $loginInfo['menus'],
'roles' => $loginInfo['roles'],
]);
}
}