1、如何给接口实现权限验证?
只要是涉及到后端那一定就需要 登录=》验证了
根据维基百科定义,JWT(读作 [/dʒɒt/]),即JSON Web Tokens,是一种基于JSON的、用于在网络上声明某种主张的令牌(token)。JWT通常由三部分组成: 头信息(header), 消息体(payload)和签名(signature)。它是一种用于双方之间传递安全信息的表述性声明规范。JWT作为一个开放的标准(RFC 7519),定义了一种简洁的、自包含的方法,从而使通信双方实现以JSON对象的形式安全的传递信息。
以上是JWT的官方解释,可以看出JWT并不是一种只能权限验证的工具,而是一种标准化的数据传输规范。所以,只要是在系统之间需要传输简短但却需要一定安全等级的数据时,都可以使用JWT规范来传输。规范是不因平台而受限制的,这也是JWT做为授权验证可以跨平台的原因。
如果理解还是有困难的话,我们可以拿JWT和JSON类比:
JSON是一种轻量级的数据交换格式,是一种数据层次结构规范。它并不是只用来给接口传递数据的工具,只要有层级结构的数据都可以使用JSON来存储和表示。当然,JSON也是跨平台的,不管是Win还是Linux,.NET还是Java,都可以使用它作为数据传输形式。
1)客户端向授权服务系统发起请求,申请获取“令牌”。
2)授权服务根据用户身份,生成一张专属“令牌”,并将该“令牌”以JWT规范返回给客户端
3)客户端将获取到的“令牌”放到http请求的headers中后,向主服务系统发起请求。主服务系统收到请求后会从headers中获取“令牌”,并从“令牌”中解析出该用户的身份权限,然后做出相应的处理(同意或拒绝返回资源)
零、生成 Token 令牌
关于JWT授权,其实过程是很简单的,大家其实这个时候静下心想一想就能明白,这个就是四步走:
首先我们需要一个具有一定规则的 Token 令牌,也就是 JWT 令牌(比如我们的公司门禁卡),//登录
然后呢,我们再定义哪些地方需要什么样的角色(比如领导办公室我们是没办法进去的),//授权机制
接下来,整个公司需要定一个规则,就是如何对这个 Token 进行验证,不能随便写个字条,这样容易被造假(比如我们公司门上的每一道刷卡机),//认证方案
最后,就是安全部门,开启认证中间件服务(那这个服务可以关闭的,比如我们电影里看到的黑客会把这个服务给关掉,这样整个公司安保就形同虚设了)。//开启中间件
这个实体类就是用来生成 Token 的,代码记录如下:
namespace Login.Service.Jwt
{
public class CustomJWTService : ICustomJWTService//抽象ICustomJWTService,具体实现CustomJWTService
{
private readonly JWTTokenOptions _JWTTokenOptions;//构造一个加密key的算法
/// <summary>
///
/// </summary>
/// <param name="jwtTokenOptions"></param>
public CustomJWTService(IOptionsMonitor<JWTTokenOptions> jwtTokenOptions)
{
_JWTTokenOptions = jwtTokenOptions.CurrentValue;
}
/// <summary>
/// 获取token,
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public string GetToken(UserRes user)
{
var claims = new[]
{
//准备有效载荷
new Claim("Id",user.Id.ToString()),
new Claim("NickName",user.NickName),
new Claim("UserName",user.UserName),
};
//需要加密:需要加密key:
//Nuget引入:Microsoft.IdentityModel.Tokens
SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_JWTTokenOptions.SecurityKey));
//指定加密算法
SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
//Nuget引入:System.IdentityModel.Tokens.Jwt
JwtSecurityToken token = new JwtSecurityToken(
issuer: _JWTTokenOptions.Issuer,//校验数据
audience: _JWTTokenOptions.Audience,
claims: claims,
expires: DateTime.Now.AddMinutes(5),//5分钟有效期
signingCredentials: creds);
string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
return returnToken;
}
}
}
抽象类 获取token
namespace Login.Service.Jwt
{
public interface ICustomJWTService
{
string GetToken(UserRes user);//颁发token
}
}
这里边有一个 Appsettings 类,主要的作用是自动读取项目配置文件 appsettings.json 。
"AllowedHosts": "*",
"JWTTokenOptions": {
"Audience": "http://localhost:8080",
"Issuer": "http://localhost:8080",
"SecurityKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB"
}
}
这个接口如何调用呢,很简单,就是我们的登录api:
namespace Login.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
//[Authorize]
public class LoginController : ControllerBase
{
public IUserService _userService;//全局的外面的
public ICustomJWTService _customJWTService;
public LoginController(IUserService userService, ICustomJWTService customJWTService)
{
_userService = userService;//里面的
_customJWTService = customJWTService;
}
/// <summary>
/// 登录
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
[HttpPost]
//[Authorize]//授权
public ApiResult Check(UserReq req)
{
ApiResult apiResult = new ApiResult() { IsSuccess = false };
if (string.IsNullOrEmpty(req.UserName) || string.IsNullOrEmpty(req.Password))
{
apiResult.Msg = "参数不能为空!";
}
else
{
UserRes user = _userService.GetUsers(req);
if (string.IsNullOrEmpty(user.UserName))
{
apiResult.Msg = "账号不存在,用户名或密码错误!";
}
else
{
apiResult.IsSuccess = true;
apiResult.Result = _customJWTService.GetToken(user);
}
}
return apiResult;
}
}
}
现在我们获取到Token了,那如何进行授权认证呢,别着急,重头戏马上到来!