生成JWT
JWT全称:Json Web Token 即用Json格式来保存令牌信息
用户登录成功后,得到一个令牌,以后每次请求时都带上令牌,令牌保存在客户端,
为了防止客户端数据造假,令牌经过签名处理,而签名的密钥只有服务器端才知道,每次服务器收到客户端的请求,都会用密钥验证令牌是否被篡改过,如果被篡改过则拒绝请求。
public class JwtHelper
{
private readonly UserManager<User> _userManager;
public JwtHelper(UserManager<User> userManager)
{
_userManager = userManager;
}
/// <summary>
/// 生成JWT令牌
/// </summary>
/// <param name="SigningKey">签名Key</param>
/// <param name="ExpireSeconds">Token过期时间,单位秒</param>
/// <returns></returns>
public async Task<string> GenerateJWT(User user, string signingKey, string expireSeconds)
{
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));
claims.Add(new Claim(ClaimTypes.Name, user.UserName));
var roles = await _userManager.GetRolesAsync(user);
foreach (string role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
claims.Add(new Claim(ClaimTypes.Email, user.Email));
DateTime expires = DateTime.Now.AddSeconds(Convert.ToDouble(expireSeconds));
byte[] secBytes = Encoding.UTF8.GetBytes(signingKey);
var secKey = new SymmetricSecurityKey(secBytes);
var credentials = new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256);
var tokenDescriptor = new JwtSecurityToken(claims: claims, expires: expires, signingCredentials: credentials);
string jwt = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
return jwt;
}
}
appsetting配置文件:
"JWT": {
"SigningKey": "ldjsfjdsklfh89789KJHKHIuyh",
"ExpireSeconds": "3600"
}
program注册服务:
services.Configure<JWTOptions>(builder.Configuration.GetSection("JWT"));
services.AddScoped<JwtHelper,JwtHelper>();
登录获取Token
using CAPWebApplication.Config;
using CAPWebApplication.Entities;
using CAPWebApplication.Tools;
using CAPWebApplication.ViewModel;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.Security.Claims;
namespace CAPWebApplication.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UserRoleController : ControllerBase
{
private readonly ILogger<UserRoleController> m_logger;
private readonly UserManager<User> m_userManager;
private readonly RoleManager<Role> m_roleManager;
private readonly IOptions<JWTOptions> m_JWTOptions;
private readonly JwtHelper m_JwtHelper;
public UserRoleController(ILogger<UserRoleController> logger, UserManager<User> userManager, RoleManager<Role> roleManager, IOptions<JWTOptions> jWTOptions = null, JwtHelper jwtHelper = null)
{
m_logger = logger;
m_userManager = userManager;
m_roleManager = roleManager;
m_JWTOptions = jWTOptions;
m_JwtHelper = jwtHelper;
}
[Route(nameof(Login))]
[HttpPost]
public async Task<ActionResult> Login(UserViewModel model)
{//验证用户名和密码
if (model == null || string.IsNullOrEmpty(model.UserName) ||
string.IsNullOrEmpty(model.Password))
{
return BadRequest();
}
var user = await m_userManager.FindByNameAsync(model.UserName);
if (user == null)
{
return NotFound($"用户名不存在{model.UserName}");
}
if (await m_userManager.IsLockedOutAsync(user))
return BadRequest("LockedOut");
var success = await m_userManager.CheckPasswordAsync(user, model.Password);
if (success)
{//登录成功返回Token
string jwtToken = await m_JwtHelper.GenerateJWT(user, m_JWTOptions.Value.SigningKey, m_JWTOptions.Value.ExpireSeconds);
return Ok(jwtToken);
}
else
{
await m_userManager.AccessFailedAsync(user);
return BadRequest("密码错误");
}
}
}
}
[Authorize]
[Route(nameof(GetUserRole))]
[HttpGet]
public async Task<ActionResult> GetUserRole()
{//读取当前登录用户User的信息
string id = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
string userName = this.User.FindFirst(ClaimTypes.Name)!.Value;
IEnumerable<Claim> roleClaims = this.User.FindAll(ClaimTypes.Role);
string roleNames = string.Join(',', roleClaims.Select(c => c.Value));
return Ok($"Id={id},UserName={userName},Roles={roleNames}");
}
浙公网安备 33010602011771号