生成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}"); }