[TOOL/CURL] curl 명령 : HTTP DELETE 요청에서 데이터 삭제 요청하기
■ curl 명령을 사용해 HTTP DELETE 요청에서 데이터 삭제를 요청하는 방법을 보여준다. 1. [명령 프롬프트]를 실행한다. 2. [명령 프롬프트]에서 아래 명령을 실행한다.
■ curl 명령을 사용해 HTTP DELETE 요청에서 데이터 삭제를 요청하는 방법을 보여준다. 1. [명령 프롬프트]를 실행한다. 2. [명령 프롬프트]에서 아래 명령을 실행한다.
■ curl 명령을 사용해 HTTP PUT 요청에서 데이터 수정을 요청하는 방법을 보여준다. 1. [명령 프롬프트]를 실행한다. 2. [명령 프롬프트]에서 아래 명령을 실행한다.
■ curl 명령을 사용해 HTTP POST 요청에서 JWT 토큰을 포함한 신규 데이터 추가를 요청하는 방법을 보여준다. 1. [명령 프롬프트]를 실행한다. 2. [명령
■ FastAPI 클래스를 사용해 JWT 인증 애플리케이션을 만드는 방법을 보여준다. (MongoDB 연동) ▶ .env
1 2 3 4 |
DATABASE_URL=mongodb://localhost:27017/testdb SECRET_KEY=pass1234567 |
※ testdb : MongoDB 데이터베이스명 ※ pass1234567
■ JWT 토큰을 생성하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using Microsoft.IdentityModel.Tokens; #region JWT 토큰 생성하기 - GenerateJWTToken(claimEnumerable, secretKey, issuer, audience) /// <summary> /// JWT 토큰 생성하기 /// </summary> /// <param name="claimEnumerable">클레임 열거 가능형</param> /// <param name="secretKey">비밀 키</param> /// <param name="issuer">발행자</param> /// <param name="audience">청취자</param> /// <returns>JWT 토큰</returns> public string GenerateJWTToken(IEnumerable<Claim> claimEnumerable, string secretKey, string issuer, string audience) { byte[] keyByteArray = Encoding.UTF8.GetBytes(secretKey); SymmetricSecurityKey symmetricSecurityKey = new(keyByteArray); SigningCredentials credentials = new(symmetricSecurityKey, SecurityAlgorithms.HmacSha256); JwtSecurityToken token = new ( issuer : issuer, audience : audience, claims : claimEnumerable, expires : DateTime.Now.AddHours(1), signingCredentials : credentials ); string tokenString = new JwtSecurityTokenHandler().WriteToken(token); return tokenString; } #endregion |
■ JWT 토큰에서 클레임 주체를 구하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
using System; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using Microsoft.IdentityModel.Tokens; #region 클레임 주체 구하기 - GetClaimsPrincipal(token, secretKey) /// <summary> /// 클레임 주체 구하기 /// </summary> /// <param name="token">토큰</param> /// <param name="secretKey">비밀 키</param> /// <returns>클레임 주체</returns> public ClaimsPrincipal GetClaimsPrincipal(string token, string secretKey) { TokenValidationParameters parameters = new() { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = false, ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)), }; JwtSecurityTokenHandler tokenHandler = new(); ClaimsPrincipal principal = tokenHandler.ValidateToken(token, parameters, out SecurityToken securityToken); if ( securityToken is not JwtSecurityToken jwtSecurityToken || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase) ) { throw new SecurityTokenException("Invalid token"); } return principal; } #endregion |
■ WEB API에서 JWT(Json Web Token) 인증을 사용하는 방법을 보여준다. [TestLibrary 프로젝트] ▶ User.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
namespace TestLibrary { /// <summary> /// 사용자 /// </summary> public class User { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 사용자명 - UserName /// <summary> /// 사용자명 /// </summary> public string UserName { get; set; } #endregion #region 패스워드 - Password /// <summary> /// 패스워드 /// </summary> public string Password { get; set; } #endregion #region 사용자 역할 - UserRole /// <summary> /// 사용자 역할 /// </summary> public string UserRole { get; set; } #endregion } } |
▶ WeatherForecast.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
using System; namespace TestLibrary { /// <summary> /// 기상 예보 /// </summary> public class WeatherForecast { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 일자 - Date /// <summary> /// 일자 /// </summary> public DateTime Date { get; set; } #endregion #region 섭씨 온도 - TemperatureC /// <summary> /// 섭씨 온도 /// </summary> public int TemperatureC { get; set; } #endregion #region 화씨 온도 - TemperatureF /// <summary> /// 화씨 온도 /// </summary> public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); #endregion #region 요약 - Summary /// <summary> /// 요약 /// </summary> public string Summary { get; set; } #endregion } } |
[TestServer 프로젝트] ▶ appsettings.json
■ OAuth 인증을 사용하는 방법을 보여준다. (액세스 토큰 갱신 추가) [TestAuthorizationServer 프로젝트] ▶ Properties/launchSettings.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
{ "iisSettings" : { "windowsAuthentication" : false, "anonymousAuthentication" : true, "iisExpress" : { "applicationUrl" : "http://localhost:50000", "sslPort" : 44300 } }, "profiles" : { "IIS Express" : { "commandName" : "IISExpress", "launchBrowser" : true, "environmentVariables" : { "ASPNETCORE_ENVIRONMENT" : "Development" } }, "TestAuthorizationServer" : { "commandName" : "Project", "launchBrowser" : true, "applicationUrl" : "https://localhost:5001;http://localhost:5000", "environmentVariables" : { "ASPNETCORE_ENVIRONMENT" : "Development" } } } } |
▶ ConstantHelper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
namespace TestAuthorizationServer { /// <summary> /// 상수 헬퍼 /// </summary> public class ConstantHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 발급자 /// </summary> public const string Issuer = Audiance; /// <summary> /// 청중 /// </summary> public const string Audiance = "https://localhost:44300/"; /// <summary> /// 패스워드 /// </summary> public const string Password = "not_too_short_secret_otherwise_it_might_error"; #endregion } } |
▶ Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.IdentityModel.Tokens; using System; using System.Text; using System.Threading.Tasks; namespace TestAuthorizationServer { /// <summary> /// 시작 /// </summary> public class Startup { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 서비스 컬렉션 구성하기 - ConfigureServices(services) /// <summary> /// 서비스 컬렉션 구성하기 /// </summary> /// <param name="services">서비스 컬렉션</param> public void ConfigureServices(IServiceCollection services) { services.AddAuthentication("OAuth") .AddJwtBearer ( "OAuth", options => { byte[] passwordByteArray = Encoding.UTF8.GetBytes(ConstantHelper.Password); SymmetricSecurityKey key = new SymmetricSecurityKey(passwordByteArray); options.Events = new JwtBearerEvents() { OnMessageReceived = context => { if(context.Request.Query.ContainsKey("access_token")) { context.Token = context.Request.Query["access_token"]; } return Task.CompletedTask; } }; options.TokenValidationParameters = new TokenValidationParameters() { ClockSkew = TimeSpan.Zero, ValidIssuer = ConstantHelper.Issuer, ValidAudience = ConstantHelper.Audiance, IssuerSigningKey = key }; } ); services.AddControllersWithViews() .AddRazorRuntimeCompilation(); } #endregion #region 구성하기 - Configure(app, environment) /// <summary> /// 구성하기 /// </summary> /// <param name="app">애플리케이션 빌더</param> /// <param name="environment">웹 호스트 환경</param> public void Configure(IApplicationBuilder app, IWebHostEnvironment environment) { if(environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints ( endpoints => { endpoints.MapDefaultControllerRoute(); } ); } #endregion } } |
▶
■ OAuth 인증을 사용하는 방법을 보여준다. (API 서버 추가) [TestAuthorizationServer 프로젝트] ▶ Properties/launchSettings.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
{ "iisSettings" : { "windowsAuthentication" : false, "anonymousAuthentication" : true, "iisExpress" : { "applicationUrl" : "http://localhost:50000", "sslPort" : 44300 } }, "profiles" : { "IIS Express" : { "commandName" : "IISExpress", "launchBrowser" : true, "environmentVariables" : { "ASPNETCORE_ENVIRONMENT" : "Development" } }, "TestAuthorizationServer" : { "commandName" : "Project", "launchBrowser" : true, "applicationUrl" : "https://localhost:5001;http://localhost:5000", "environmentVariables" : { "ASPNETCORE_ENVIRONMENT" : "Development" } } } } |
▶ ConstantHelper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
namespace TestAuthorizationServer { /// <summary> /// 상수 헬퍼 /// </summary> public class ConstantHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 발급자 /// </summary> public const string Issuer = Audiance; /// <summary> /// 청중 /// </summary> public const string Audiance = "https://localhost:44300/"; /// <summary> /// 패스워드 /// </summary> public const string Password = "not_too_short_secret_otherwise_it_might_error"; #endregion } } |
▶ Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.IdentityModel.Tokens; using System.Text; using System.Threading.Tasks; namespace TestAuthorizationServer { /// <summary> /// 시작 /// </summary> public class Startup { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 서비스 컬렉션 구성하기 - ConfigureServices(services) /// <summary> /// 서비스 컬렉션 구성하기 /// </summary> /// <param name="services">서비스 컬렉션</param> public void ConfigureServices(IServiceCollection services) { services.AddAuthentication("OAuth") .AddJwtBearer ( "OAuth", options => { byte[] passwordByteArray = Encoding.UTF8.GetBytes(ConstantHelper.Password); SymmetricSecurityKey key = new SymmetricSecurityKey(passwordByteArray); options.Events = new JwtBearerEvents() { OnMessageReceived = context => { if(context.Request.Query.ContainsKey("access_token")) { context.Token = context.Request.Query["access_token"]; } return Task.CompletedTask; } }; options.TokenValidationParameters = new TokenValidationParameters() { ValidIssuer = ConstantHelper.Issuer, ValidAudience = ConstantHelper.Audiance, IssuerSigningKey = key }; } ); services.AddControllersWithViews() .AddRazorRuntimeCompilation(); } #endregion #region 구성하기 - Configure(app, environment) /// <summary> /// 구성하기 /// </summary> /// <param name="app">애플리케이션 빌더</param> /// <param name="environment">웹 호스트 환경</param> public void Configure(IApplicationBuilder app, IWebHostEnvironment environment) { if(environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints ( endpoints => { endpoints.MapDefaultControllerRoute(); } ); } #endregion } } |
▶ Controllers/HomeController.cs
■ OAuth 인증을 사용하는 방법을 보여준다. [TestServer 프로젝트] ▶ launchSettings.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
{ "iisSettings" : { "windowsAuthentication" : false, "anonymousAuthentication" : true, "iisExpress" : { "applicationUrl" : "http://localhost:9389", "sslPort" : 44373 } }, "profiles" : { "IIS Express" : { "commandName" : "IISExpress", "launchBrowser" : true, "environmentVariables" : { "ASPNETCORE_ENVIRONMENT" : "Development" } }, "TestServer" : { "commandName" : "Project", "launchBrowser" : true, "applicationUrl" : "https://localhost:5001;http://localhost:5000", "environmentVariables" : { "ASPNETCORE_ENVIRONMENT" : "Development" } } } } |
▶ ConstantHelper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
namespace TestServer { /// <summary> /// 상수 헬퍼 /// </summary> public class ConstantHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 발급자 /// </summary> public const string Issuer = Audiance; /// <summary> /// 청중 /// </summary> public const string Audiance = "https://localhost:44373/"; /// <summary> /// 패스워드 /// </summary> public const string Password = "not_too_short_secret_otherwise_it_might_error"; #endregion } } |
▶ Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.IdentityModel.Tokens; using System.Text; using System.Threading.Tasks; namespace TestServer { /// <summary> /// 시작 /// </summary> public class Startup { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 서비스 컬렉션 구성하기 - ConfigureServices(services) /// <summary> /// 서비스 컬렉션 구성하기 /// </summary> /// <param name="services">서비스 컬렉션</param> public void ConfigureServices(IServiceCollection services) { services.AddAuthentication("OAuth") .AddJwtBearer ( "OAuth", options => { byte[] passwordByteArray = Encoding.UTF8.GetBytes(ConstantHelper.Password); SymmetricSecurityKey key = new SymmetricSecurityKey(passwordByteArray); options.Events = new JwtBearerEvents() { OnMessageReceived = context => { if(context.Request.Query.ContainsKey("access_token")) { context.Token = context.Request.Query["access_token"]; } return Task.CompletedTask; } }; options.TokenValidationParameters = new TokenValidationParameters() { ValidIssuer = ConstantHelper.Issuer, ValidAudience = ConstantHelper.Audiance, IssuerSigningKey = key }; } ); services.AddControllersWithViews() .AddRazorRuntimeCompilation(); } #endregion #region 구성하기 - Configure(app, environment) /// <summary> /// 구성하기 /// </summary> /// <param name="app">애플리케이션 빌더</param> /// <param name="environment">웹 호스트 환경</param> public void Configure(IApplicationBuilder app, IWebHostEnvironment environment) { if(environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints ( endpoints => { endpoints.MapDefaultControllerRoute(); } ); } #endregion } } |
▶ Controllers/OAuthController.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.IdentityModel.Tokens; using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; namespace TestServer.Controllers { /// <summary> /// OAUTH 컨트롤러 /// </summary> public class OAuthController : Controller { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 로그인 페이지 처리하기 - Login(client_id, scope, response_type, redirect_uri, state) /// <summary> /// 로그인 페이지 처리하기 /// </summary> /// <param name="client_id">클라이언트 ID</param> /// <param name="scope">범위</param> /// <param name="response_type">인증 플로우 타입</param> /// <param name="redirect_uri">재전송 URI</param> /// <param name="state">상태</param> /// <returns>액션 결과</returns> [HttpGet] public IActionResult Login(string client_id, string scope, string response_type, string redirect_uri, string state) { QueryBuilder queryBuilder = new QueryBuilder(); queryBuilder.Add("redirectURI", redirect_uri); queryBuilder.Add("state" , state ); return View(model : queryBuilder.ToString()); } #endregion #region 로그인 페이지 처리하기 - Login(userName, password, redirectURI, state) /// <summary> /// 로그인 페이지 처리하기 /// </summary> /// <param name="userName">사용자명</param> /// <param name="password">패스워드</param> /// <param name="redirectURI">재전송 URI</param> /// <param name="state">상태</param> /// <returns>액션 결과</returns> [HttpPost] public IActionResult Login(string userName, string password, string redirectURI, string state) { const string code = "BABABABABA"; // 사용자명과 패스워드에 따라 code를 설정한다. QueryBuilder queryBuilder = new QueryBuilder(); queryBuilder.Add("code" , code ); queryBuilder.Add("state", state); return Redirect($"{redirectURI}{queryBuilder.ToString()}"); } #endregion #region 토큰 페이지 처리하기 - Token(grant_type, code, redirect_uri, client_id) /// <summary> /// 토큰 페이지 처리하기 /// </summary> /// <param name="grant_type">그랜트 타입</param> /// <param name="code">코드</param> /// <param name="redirect_uri">재전송 URI</param> /// <param name="client_id">클라이언트 ID</param> /// <returns></returns> public async Task<IActionResult> Token(string grant_type, string code, string redirect_uri, string client_id) { // code 값에 따라 JWT를 발행한다. List<Claim> claimList = new List<Claim>() { new Claim(JwtRegisteredClaimNames.Sub , "ID0001" ), new Claim(JwtRegisteredClaimNames.Birthdate, "1990-01-01" ), new Claim(JwtRegisteredClaimNames.Email , "test@daum.net"), new Claim(JwtRegisteredClaimNames.Gender , "Male" ), new Claim("CompanyGroup" , "영업1그룹" ), new Claim("CompanyDepartment" , "영업1팀" ), new Claim("CompanyTitle" , "대리" ), new Claim("EmployeeID" , "EMP0001" ), new Claim("EmployeeName" , "홍길동" ) }; byte[] passwordByteArray = Encoding.UTF8.GetBytes(ConstantHelper.Password); SymmetricSecurityKey key = new SymmetricSecurityKey(passwordByteArray); string algorithm = SecurityAlgorithms.HmacSha256; SigningCredentials signingCredentials = new SigningCredentials(key, algorithm); JwtSecurityToken token = new JwtSecurityToken ( ConstantHelper.Issuer, ConstantHelper.Audiance, claimList, notBefore : DateTime.Now, expires : DateTime.Now.AddHours(1), signingCredentials ); string access_token = new JwtSecurityTokenHandler().WriteToken(token); var responseObject = new { access_token, token_type = "Bearer", raw_claim = "oauthTurorial" }; string responseJSON = JsonConvert.SerializeObject(responseObject); byte[] responseByteArray = Encoding.UTF8.GetBytes(responseJSON); await Response.Body.WriteAsync(responseByteArray, 0, responseByteArray.Length); return Redirect(redirect_uri); } #endregion } } |
▶ Views/OAuth/Loging.cshtml
■ JWT(Json Web Token) 인증을 사용하는 방법을 보여준다. ※ JWT 기본 개념을 이해하기 위한 소스 코드이다. ▶ ConstantHelper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
namespace TestProject { /// <summary> /// 상수 헬퍼 /// </summary> public class ConstantHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 발행자 /// </summary> public const string Issuer = "https://localhost:44306/"; /// <summary> /// 청중 /// </summary> public const string Audiance = "https://localhost:44306/"; /// <summary> /// 패스워드 /// </summary> public const string Password = "not_too_short_secret_otherwise_it_might_error"; #endregion } } |
※ Issuer, Audiance,
■ Microsoft.AspNetCore.Authentication.JwtBearer 누겟을 설치하는 방법을 보여준다. 1. Visual Studio를 실행한다. 2. [도구] / [NuGet 패키지 관리자] / [패키지 관리자 콘솔] 메뉴를 실행한다.
■ JWT(Json Web Token) 인증을 사용하는 방법을 보여준다. [TestLibrary 프로젝트] ▶ Models/UserModel.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
namespace TestLibrary.Models { /// <summary> /// 사용자 /// </summary> public class UserModel { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region ID - ID /// <summary> /// ID /// </summary> public int ID { get; set; } #endregion #region 사용자명 - UserName /// <summary> /// 사용자명 /// </summary> public string UserName { get; set; } #endregion #region 패스워드 - Password /// <summary> /// 패스워드 /// </summary> public string Password { get; set; } #endregion } } |
▶ Models/TestModel.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
namespace TestLibrary.Models { /// <summary> /// 테스트 모델 /// </summary> public class TestModel { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 값 - Value /// <summary> /// 값 /// </summary> public string Value { get; set; } #endregion } } |
[TestClient 프로젝트] ▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
using System; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; using TestLibrary.Models; namespace TestClient { /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> static void Main() { UserModel user = new UserModel { UserName = "admin", Password = "1234"}; string token = Login("http://localhost:4035/api/authentication/login", user).GetAwaiter().GetResult(); Console.WriteLine($"JWT 토큰 : {token}"); Console.WriteLine("--------------------------------------------------"); TestModel test = new TestModel { Value = "테스트" }; string result = Test("http://localhost:4035/api/authentication/test", token, test).GetAwaiter().GetResult(); Console.WriteLine($"결과 : {result}"); Console.WriteLine("--------------------------------------------------"); Console.WriteLine("아무 키나 눌러 주시기 바랍니다."); Console.ReadKey(true); } #endregion #region HTTP 클라이언트 구하기 - GetHTTPClient(useCookie, baseAddress, tokenShema, token) /// <summary> /// HTTP 클라이언트 구하기 /// </summary> /// <param name="useCookie">쿠키 사용 여부</param> /// <param name="baseAddress">기본 주소</param> /// <param name="tokenShema">토큰 스키마</param> /// <param name="token">토큰</param> /// <returns>HTTP 클라이언트</returns> private static HttpClient GetHTTPClient(bool useCookie, string baseAddress, string tokenShema, string token) { HttpClient client; if(useCookie) { HttpClientHandler httpClientHandler = new HttpClientHandler(); httpClientHandler.UseCookies = true; httpClientHandler.CookieContainer = new CookieContainer(); client = new HttpClient(httpClientHandler); } else { client = new HttpClient(); } client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); if(!string.IsNullOrWhiteSpace(baseAddress)) { client.BaseAddress = new Uri(baseAddress); } if(!string.IsNullOrWhiteSpace(tokenShema)) { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(tokenShema, token); } return client; } #endregion #region 로그인하기 - Login(url, user) /// <summary> /// 로그인하기 /// </summary> /// <param name="url">URL</param> /// <param name="user">사용자</param> /// <returns>JWT 토큰</returns> private static async Task<string> Login(string url, UserModel user) { using(HttpClient client = GetHTTPClient(false, url, null, null)) { var response = await client.PostAsJsonAsync<UserModel>(url, user); if(response.IsSuccessStatusCode) { string token = await response.Content.ReadAsAsync<string>(); return token; } return null; } } #endregion #region 테스트하기 - Test(url, token, test) /// <summary> /// 테스트하기 /// </summary> /// <param name="url">URL</param> /// <param name="token">JWT 토큰</param> /// <param name="test">테스트</param> /// <returns>테스트 결과</returns> private static async Task<string> Test(string url, string token, TestModel test) { using(HttpClient client = GetHTTPClient(false, url, "Bearer", token)) { var response = await client.PostAsJsonAsync<TestModel>(url, test); if(response.IsSuccessStatusCode) { string result = await response.Content.ReadAsAsync<string>(); return result; } else // http://로 호출한 경우 https://로 다시 호출한다. { string finalRequestURL = response.RequestMessage.RequestUri.AbsoluteUri; if(finalRequestURL != url) { response = await client.PostAsJsonAsync<TestModel>(finalRequestURL, test); if(response.IsSuccessStatusCode) { string result = await response.Content.ReadAsAsync<string>(); return result; } else { return null; } } else { return null; } } } } #endregion } } |
[TestServer