ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了 - 依乐祝 - 博客园
cookie、session、token、OAuth
参考网址:授权认证登录之 Cookie、Session、Token、JWT 详解 - 黄金国的大象 - 博客园
.Net5 Core 配置 Swagger 并进行全局Token添加 - lilyshy - 博客园
视频学习:【Asp.NetCoreWebApi】开发实战完整带源码(集成日志/搭建服务器实例集群/Jwt鉴权授权/Filter扩展定制)_哔哩哔哩_bilibili
Cookie
cookie 存储在客户端: cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。
cookie 是不可跨域的: 每个 cookie 都会绑定单一的域名,无法在别的域名下获取使用,一级域名和二级域名之间是允许共享使用的(靠的是 domain)。
Session
session 是基于 cookie 实现的,session 存储在服务器端,sessionId 会被存储到客户端的cookie 中
Cookie 和 Session 的区别
安全性: Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的。
存取值的类型不同:Cookie 只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session 可以存任意数据类型。
有效期不同: Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效。
存储大小不同: 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。
JWT(JSON Web Token)
JWT 的三个部分依次如下:Header(头部),Payload(负载),Signature(签名)
需要请求头的 Authorization 字段中使用Bearer 模式添加 JWT Authorization: Bearer <token>
JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输
Token refresh token access token
cookie localStorage
Base64-URL字符串
非对称可逆加密,私钥,公钥
Nuget 安装 Microsoft.AspNetCore.Authentication.JwtBearer
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace YueYue.Core.AuthenticationCenter.Utility
{
public interface IJWTService {
string GetToken(string UserName);
}
public class JWTService:IJWTService
{
private readonly IConfiguration _configuration;
public JWTService(IConfiguration configuration) {
_configuration = configuration;
}
public string GetToken(string UserName)
{
Claim[] claims = new[]
{
new Claim(ClaimTypes.Name, UserName),
new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds()}"),
new Claim("other","其他信息")
};
SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecurityKey"]));
SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _configuration["issuer"],
audience: _configuration["audience"],
claims: claims,
expires: DateTime.Now.AddMinutes(30), //30分钟有效期
signingCredentials: creds);
string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
return returnToken;
}
}
}
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"issuer": "http://localhost:5000",
"audience": "http://localhost:5000",
"SecurityKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB"
}
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IJWTService, JWTService>();
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "YueYue.Core.AuthenticationCenter", Version = "v1" });
c.DocInclusionPredicate((docName, description) => true);
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "JWT授权(数据将在请求头中进行传输) 在下方输入Bearer {token} 即可,注意两者之间有空格",
Name = "Authorization",//jwt默认的参数名称
In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
Type = SecuritySchemeType.ApiKey
});
//认证方式,此方式为全局添加
c.AddSecurityRequirement(new OpenApiSecurityRequirement {
{ new OpenApiSecurityScheme
{
Reference = new OpenApiReference()
{
Id = "Bearer",
Type = ReferenceType.SecurityScheme
}
}, Array.Empty<string>() }
});
});
//添加jwt验证:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,//是否验证Issuer
ValidateAudience = true,//是否验证Audience
ValidateLifetime = true,//是否验证失效时间
ClockSkew = TimeSpan.FromSeconds(30),
ValidateIssuerSigningKey = true,//是否验证SecurityKey
ValidAudience = Configuration["audience"],//Audience
ValidIssuer = Configuration["issuer"],//Issuer,这两项和前面签发jwt的设置一致
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SecurityKey"]))//拿到SecurityKey
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "YueYue.Core.AuthenticationCenter v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication(); //通过中间件来支持鉴权授权
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using YueYue.Core.AuthenticationCenter.Utility;
namespace YueYue.Core.AuthenticationCenter.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AuthenticationController : ControllerBase
{
private ILogger<AuthenticationController> _logger = null;
private IJWTService _iJWTService = null;
private readonly IConfiguration _configuration;
public AuthenticationController(ILogger<AuthenticationController> logger, IJWTService jWTService, IConfiguration configuration) {
this._logger = logger;
_iJWTService = jWTService;
_configuration = configuration;
}
[Route("Get")]
[HttpGet]
public IEnumerable<int> Get()
{//未加授权认证
return new List<int>() { 1, 3, 5, 7, 9 };
}
[Route("GetData")]
[HttpGet]
[Authorize]
public List<object> GetData()
{//添加了授权认证,需要使用token
return new List<object>() { new { userName="酷悦悦",remark="备注信息" } };
}
[Route("Login")]
[HttpGet]
public string Login(string name, string password) {
if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(password))
{
string token = this._iJWTService.GetToken(name);
return JsonConvert.SerializeObject(new {result=true,token });
}
else {
return JsonConvert.SerializeObject(new { result = false, token = "" });
}
}
}
}