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/1 →
value
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