在asp.net core2.0 中使用jwt token保護(hù)你的API

image.png
image.png

Preface:

最近看到.net core很火纳鼎,忍不住體驗(yàn)了一把建车,發(fā)現(xiàn)微軟一直在進(jìn)步±┙瑁現(xiàn)在的.net core2.0, 除了生態(tài)不是很完善(和java系沒法比),從開發(fā)體驗(yàn)缤至、語言等各個方面潮罪,已經(jīng)足夠優(yōu)秀了∑啾跨平臺不說了错洁,關(guān)鍵是開發(fā)工具,Visual Studio簡直要甩IDEA好幾條街啊有木有~~戒突。
但是到了驗(yàn)證這個環(huán)節(jié)屯碴,微軟給出了很多個驗(yàn)證方式,甚至還有二維碼驗(yàn)證膊存,.net程序員簡直不要太幸福导而。但這些驗(yàn)證幾乎全都是基于MVC的。但是現(xiàn)在這個時代有幾個人做新項(xiàng)目還用MVC呢隔崎?不需要考慮將來的移動端擴(kuò)展么今艺?
驗(yàn)證這個環(huán)節(jié)基于Token的jwt才是王道,但官方教程并沒有給出明確的示范爵卒,上網(wǎng)搜國內(nèi)國外的基本都基于core1.0版本虚缎,步驟很繁瑣。偶然之間發(fā)現(xiàn)一篇教程钓株,基于2.0实牡,發(fā)現(xiàn)步驟大大簡化,簡化的我都能看懂了轴合,自己實(shí)踐了一下記錄下來:

1. 生成jwt token

在.net core 2.0中创坞,生成jwt token的工作被大大簡化了,只需要在控制器中聲明一個方法即可,步驟:
1). 使用一個secret key(自定義)生成Credential受葛。
2). 生成token

完整的Controller代碼如下:

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;

namespace DotnetCore2_Jwt.Controllers
{
   [Produces("application/json")]
   [Route("api/Auth")]
   public class AuthController : Controller
   {
       private readonly IConfiguration _configuration;

       public AuthController(IConfiguration configuration)
       {
           _configuration = configuration;
       }

       /// <summary>
       /// login
       /// </summary>
       /// <param name="request"></param>
       /// <returns></returns>
       [AllowAnonymous]
       [HttpPost]
       public IActionResult RequestToken([FromBody] TokenRequest request)
       {
           if (request.Username == "AngelaDaddy" && request.Password == "123456")
           {
               // push the user’s name into a claim, so we can identify the user later on.
               var claims = new[]
               {
                   new Claim(ClaimTypes.Name, request.Username)
               };
               //sign the token using a secret key.This secret will be shared between your API and anything that needs to check that the token is legit.
               var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecurityKey"]));
               var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
               //.NET Core’s JwtSecurityToken class takes on the heavy lifting and actually creates the token.
               /**
                * Claims (Payload)
                   Claims 部分包含了一些跟這個 token 有關(guān)的重要信息题涨。 JWT 標(biāo)準(zhǔn)規(guī)定了一些字段偎谁,下面節(jié)選一些字段:

                   iss: The issuer of the token,token 是給誰的
                   sub: The subject of the token纲堵,token 主題
                   exp: Expiration Time巡雨。 token 過期時間,Unix 時間戳格式
                   iat: Issued At婉支。 token 創(chuàng)建時間鸯隅, Unix 時間戳格式
                   jti: JWT ID。針對當(dāng)前 token 的唯一標(biāo)識
                   除了規(guī)定的字段外向挖,可以包含其他任何 JSON 兼容的字段蝌以。
                * */
               var token = new JwtSecurityToken(
                   issuer: "yourdomain.com",
                   audience: "yourdomain.com",
                   claims: claims,
                   expires: DateTime.Now.AddMinutes(30),
                   signingCredentials: creds);

               return Ok(new
               {
                   token = new JwtSecurityTokenHandler().WriteToken(token)
               });
           }

           return BadRequest("Could not verify username and password");
       }
   }

   public class TokenRequest
   {
       public string Username { get; set; }
       public string Password { get; set; }
   }
}

appsettings.json文件中設(shè)置SecurityKey:"SecurityKey": "dd%88*377f6d&f£$$£$FdddFF33fssDG^!3",
使用Postman測試:Post: api/auth

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiQW5nZWxhRGFkZHkiLCJleHAiOjE1MTU0NTgxNTAsImlzcyI6InlvdXJkb21haW4uY29tIiwiYXVkIjoieW91cmRvbWFpbi5jb20ifQ.tFDugoIhYnXJgcucM6biqEyD_oJnwV8RPLCVn5aoa78"
}

2. 使用jwt驗(yàn)證

在Startup.js文件中,定義jwt驗(yàn)證服務(wù):

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System.Text;

namespace DotnetCore2_Jwt
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //添加jwt驗(yàn)證:
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options=> {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,//是否驗(yàn)證Issuer
                        ValidateAudience = true,//是否驗(yàn)證Audience
                        ValidateLifetime = true,//是否驗(yàn)證失效時間
                        ValidateIssuerSigningKey = true,//是否驗(yàn)證SecurityKey
                        ValidAudience = "yourdomain.com",//Audience
                        ValidIssuer = "yourdomain.com",//Issuer何之,這兩項(xiàng)和前面簽發(fā)jwt的設(shè)置一致
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SecurityKey"]))//拿到SecurityKey
                    };
                });
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseAuthentication();//注意添加這一句跟畅,啟用驗(yàn)證
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
        }
    }
}

ALL DONE.就這么簡單

3. 測試

定義一個TestController

 [Route("api/[controller]")]
    public class TestController : Controller
    {
        // GET api/values
        [HttpGet]
        [Authorize]//添加Authorize標(biāo)簽,可以加在方法上溶推,也可以加在類上
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
         // GET api/values/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }
}

啟動測試:

GET http://localhost:50276/api/test

image.png

GET http://localhost:50276/api/test/1value

POST http://localhost:50276/auth,
POST body:{"username":"AngelaDaddy","password":"123456"}

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiQW5nZWxhRGFkZHkiLCJleHAiOjE1MTU0NjE5MTMsImlzcyI6InlvdXJkb21haW4uY29tIiwiYXVkIjoieW91cmRvbWFpbi5jb20ifQ.FtkfsA4tmZ4aILnsgU-So8fgYxPIwcWRAtdsFUEITnA"
}

GET GET http://localhost:50276/api/test,在header中添加Auth

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末徊件,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蒜危,更是在濱河造成了極大的恐慌虱痕,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辐赞,死亡現(xiàn)場離奇詭異部翘,居然都是意外死亡局劲,警方通過查閱死者的電腦和手機(jī)亡脸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來猪叙,“玉大人赘风,你說我怎么就攤上這事夹囚。” “怎么了邀窃?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵荸哟,是天一觀的道長。 經(jīng)常有香客問我瞬捕,道長鞍历,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任山析,我火速辦了婚禮,結(jié)果婚禮上掏父,老公的妹妹穿的比我還像新娘笋轨。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布爵政。 她就那樣靜靜地躺著仅讽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钾挟。 梳的紋絲不亂的頭發(fā)上洁灵,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機(jī)與錄音掺出,去河邊找鬼徽千。 笑死,一個胖子當(dāng)著我的面吹牛汤锨,可吹牛的內(nèi)容都是我干的双抽。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼闲礼,長吁一口氣:“原來是場噩夢啊……” “哼牍汹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起柬泽,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤慎菲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后锨并,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體露该,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年琳疏,在試婚紗的時候發(fā)現(xiàn)自己被綠了有决。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡空盼,死狀恐怖书幕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情揽趾,我是刑警寧澤台汇,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站篱瞎,受9級特大地震影響苟呐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜俐筋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一牵素、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧澄者,春花似錦笆呆、人聲如沸请琳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俄精。三九已至,卻和暖如春榕堰,著一層夾襖步出監(jiān)牢的瞬間竖慧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工逆屡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留圾旨,地道東北人。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓康二,卻偏偏與公主長得像碳胳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子沫勿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容