学海无涯

导航

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

  

posted on 2022-10-06 16:36  宁静致远.  阅读(152)  评论(0编辑  收藏  举报