Merge pull request '[🐛] 추가 안한 Scope 코드 제거' (#44) from seonkyu.kim/AcaMate_API:main into debug
All checks were successful
Back/pipeline/head This commit looks good
All checks were successful
Back/pipeline/head This commit looks good
Reviewed-on: https://git.ipstein.myds.me/AcaMate/AcaMate_API/pulls/44
This commit is contained in:
commit
6763cd5454
|
@ -127,7 +127,7 @@ builder.Services.AddScoped<IRepositoryService, RepositoryService>();
|
||||||
builder.Services.AddScoped<IHeaderConfig, HeaderConfigRepository>();
|
builder.Services.AddScoped<IHeaderConfig, HeaderConfigRepository>();
|
||||||
|
|
||||||
builder.Services.AddScoped<IUserService, UserService>();
|
builder.Services.AddScoped<IUserService, UserService>();
|
||||||
builder.Services.AddScoped<IKakaoService, KakaoService>();
|
// builder.Services.AddScoped<IKakaoService, KakaoService>();
|
||||||
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
||||||
|
|
||||||
builder.Services.AddScoped<IAppService, AppService>();
|
builder.Services.AddScoped<IAppService, AppService>();
|
||||||
|
|
12
Program/Services/V1/Interfaces/IKakaoService.cs
Normal file
12
Program/Services/V1/Interfaces/IKakaoService.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
using Back.Program.Common.Model;
|
||||||
|
|
||||||
|
namespace Back.Program.Services.V1.Interfaces;
|
||||||
|
|
||||||
|
public interface IKakaoService
|
||||||
|
{
|
||||||
|
Task<string> GetAccessToken(string code);
|
||||||
|
Task<string> GetAuthorizationUrl(string scope);
|
||||||
|
Task<(bool Success, string Response)> Redirect(string code);
|
||||||
|
Task<(bool Success, string Response)> Logout(string accessToken);
|
||||||
|
Task<(bool Success, string Response)> Unlink(string accessToken);
|
||||||
|
}
|
135
Program/Services/V1/KakaoService.cs
Normal file
135
Program/Services/V1/KakaoService.cs
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
|
||||||
|
using Back.Program.Services.V1.Interfaces;
|
||||||
|
|
||||||
|
namespace Back.Program.Services.V1;
|
||||||
|
|
||||||
|
public class KakaoService: IKakaoService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
private const string KAKAO_API_BASE_URL = "https://kapi.kakao.com";
|
||||||
|
private const string KAKAO_AUTH_BASE_URL = "https://kauth.kakao.com";
|
||||||
|
private readonly string _clientId;
|
||||||
|
private readonly string _clientSecret;
|
||||||
|
private readonly string _redirectUri;
|
||||||
|
|
||||||
|
public KakaoService(HttpClient httpClient, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
_httpClient = httpClient;
|
||||||
|
_clientId = configuration["Kakao:ClientId"] ?? throw new InvalidOperationException("Kakao:ClientId not configured");
|
||||||
|
_redirectUri = configuration["Kakao:RedirectUri"] ?? throw new InvalidOperationException("Kakao:RedirectUri not configured");
|
||||||
|
_clientSecret = configuration["Kakao:ClientSecret"] ?? throw new InvalidOperationException("Kakao:ClientSecret not configured");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetHeaders(string accessToken)
|
||||||
|
{
|
||||||
|
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
|
||||||
|
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||||
|
}
|
||||||
|
private async Task<string> Call(HttpMethod method, string url, HttpContent? content = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var request = new HttpRequestMessage(method, url);
|
||||||
|
if (content != null)
|
||||||
|
{
|
||||||
|
request.Content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
var response = await _httpClient.SendAsync(request);
|
||||||
|
var responseContent = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
return JsonSerializer.Serialize(new { error = $"HTTP {(int)response.StatusCode}: {responseContent}" });
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseContent;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return JsonSerializer.Serialize(new { error = ex.Message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> GetAccessToken(string code)
|
||||||
|
{
|
||||||
|
var content = new FormUrlEncodedContent(new[]
|
||||||
|
{
|
||||||
|
new KeyValuePair<string, string>("grant_type", "authorization_code"),
|
||||||
|
new KeyValuePair<string, string>("client_id", _clientId),
|
||||||
|
new KeyValuePair<string, string>("redirect_uri", _redirectUri),
|
||||||
|
new KeyValuePair<string, string>("code", code),
|
||||||
|
new KeyValuePair<string, string>("client_secret", _clientSecret)
|
||||||
|
});
|
||||||
|
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
|
||||||
|
|
||||||
|
var response = await Call(HttpMethod.Post, $"{KAKAO_AUTH_BASE_URL}/oauth/token", content);
|
||||||
|
var responseData = JsonSerializer.Deserialize<JsonElement>(response);
|
||||||
|
|
||||||
|
if (responseData.TryGetProperty("error", out var error))
|
||||||
|
{
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!responseData.TryGetProperty("access_token", out var accessToken))
|
||||||
|
{
|
||||||
|
return JsonSerializer.Serialize(new { error = "Access token is missing from response" });
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsonSerializer.Serialize(new { access_token = accessToken.GetString() });
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<string> GetAuthorizationUrl(string scope)
|
||||||
|
{
|
||||||
|
var authUrl = $"{KAKAO_AUTH_BASE_URL}/oauth/authorize?client_id={_clientId}&redirect_uri={_redirectUri}&response_type=code";
|
||||||
|
if (!string.IsNullOrEmpty(scope))
|
||||||
|
{
|
||||||
|
authUrl += $"&scope={scope}";
|
||||||
|
}
|
||||||
|
return Task.FromResult(authUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(bool Success, string Response)> Redirect(string code)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(code))
|
||||||
|
return (false, JsonSerializer.Serialize(new { error = "Authorization code not found" }));
|
||||||
|
|
||||||
|
var response = await GetAccessToken(code);
|
||||||
|
var responseData = JsonSerializer.Deserialize<JsonElement>(response);
|
||||||
|
|
||||||
|
if (responseData.TryGetProperty("error", out var error))
|
||||||
|
{
|
||||||
|
return (false, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
var accessToken = responseData.GetProperty("access_token").GetString();
|
||||||
|
if (string.IsNullOrEmpty(accessToken))
|
||||||
|
{
|
||||||
|
return (false, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true, accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(bool Success, string Response)> Logout(string accessToken)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(accessToken))
|
||||||
|
return (false, JsonSerializer.Serialize(new { error = "Not logged in" }));
|
||||||
|
|
||||||
|
SetHeaders(accessToken);
|
||||||
|
var response = await Call(HttpMethod.Post, $"{KAKAO_API_BASE_URL}/v1/user/logout");
|
||||||
|
return (true, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(bool Success, string Response)> Unlink(string accessToken)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(accessToken))
|
||||||
|
return (false, JsonSerializer.Serialize(new { error = "Not logged in" }));
|
||||||
|
|
||||||
|
SetHeaders(accessToken);
|
||||||
|
var response = await Call(HttpMethod.Post, $"{KAKAO_API_BASE_URL}/v1/user/unlink");
|
||||||
|
return (true, response);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user