iT邦幫忙

2022 iThome 鐵人賽

DAY 24
2
Software Development

ASP.NET Core 30 天旅程系列 第 24

[Day24]- API 系列之 JWT 實作篇

  • 分享至 

  • xImage
  •  

先建立一個 API 專案
https://ithelp.ithome.com.tw/upload/images/20221009/20152200SYbZHwwHK3.png
https://ithelp.ithome.com.tw/upload/images/20221009/20152200s4liOmKfCL.png

建立成功後,專案預設會有一個WeatherForecastController.cs
https://ithelp.ithome.com.tw/upload/images/20221009/20152200PbscZoasuq.png

接著我們先安裝 JWT 套件
Microsoft.AspNetCore.Authentication.JwtBearer
https://ithelp.ithome.com.tw/upload/images/20221009/20152200XqbyUaJvQJ.png

建立一個 AuthController 來取得 Token

    [Route("api/[controller]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        private readonly IConfiguration _configuration;
        public AuthController(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        /// <summary>
        /// 通過賬號+密碼獲取Token
        /// </summary>
        /// <param ></param>
        /// <param ></param>
        /// <returns>Token</returns>
        [AllowAnonymous]
        [HttpGet]
        public IActionResult Get(string userName, string pwd)
        {
            if (!string.IsNullOrEmpty(userName))
            {
                var claims = new[]
                {
                    new Claim(JwtRegisteredClaimNames.Sub, userName),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) // JWT ID
            };

                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
                var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                var token = new JwtSecurityToken(
                    //頒發者
                    issuer: _configuration["Jwt:Issuer"],
                    //接收者
                    audience: _configuration["Jwt:Audience"],
                    //過期時間(可自行設定,注意和上面的claims內部Exp參數保持一致)
                    expires: DateTime.Now.AddMinutes(15),
                    //簽名證書
                    signingCredentials: creds,
                    //自定義參數
                    claims: claims
                    );
                return Ok(new
                {
                    token = new JwtSecurityTokenHandler().WriteToken(token)
                });
            }
            else
            {
                return BadRequest(new { message = "帳號或密碼失敗" });
            }
        }
    }

Program.cs

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
    o.TokenValidationParameters = new TokenValidationParameters
    {
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        ValidAudience = builder.Configuration["Jwt:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey
        (Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])),
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = false,
        ValidateIssuerSigningKey = true
    };
});
builder.Services.AddAuthorization();
...
...
...
app.UseAuthentication();
app.UseAuthorization();

appsettings.json

  "Jwt": {
    "Issuer": "https://localhost:444",
    "Audience": "https://localhost:444",
    "Key": "testtest20222022"
  }

我們在預設的 WeatherForecastController Get() 加上 [Authorize],表示在取用這個 API 時要經過授權驗證才能被取用。
https://ithelp.ithome.com.tw/upload/images/20221009/20152200Gklh6pAt77.png

測試

打開 Postman 輸入網址會發現 Response 401 Unauthorized,也就是未授權。
https://ithelp.ithome.com.tw/upload/images/20221009/20152200AGpiMuwW5u.png

取得token

利用我們在 AuthControllerGET 方法來取得,因為是測試所以帳密並沒有經過資料庫驗證,有打就算通過,我們可以看到成功時會回傳給我們 token。
https://ithelp.ithome.com.tw/upload/images/20221009/20152200vi6v2nQkeP.png

成功取到 token 後我們可以利用這個 token 暢行無阻取用 API XDDD,範例如下
https://ithelp.ithome.com.tw/upload/images/20221009/20152200Xi72wOiq8X.png

若隨便改 token 中一個字,就會變成 401。
https://ithelp.ithome.com.tw/upload/images/20221009/20152200Tarc5MrAgE.png

結語

當今 API 被廣泛的使用所以安全性的考量也變得格外重要,透過授權及驗證,可以將 API 更加安全,一般流程都會是在登入的 API 回傳的時候給 token,然後這個 token 就可以在其他 API 要取用時放在 header 裡一起送出,如果沒有 token 或 token驗證失敗會直接回傳 401 並不會進入到 Controller裡面。


上一篇
[Day23]- API系列之 Postman
下一篇
[Day25]-模型驗證
系列文
ASP.NET Core 30 天旅程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言