WGShare.API/WGShare.API/Controllers/AuthController.cs

280 lines
10 KiB
C#

using Masuit.Tools;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using NetTaste;
using SqlSugar;
using System.Configuration;
using System.Security.Claims;
using WGShare.API.Controllers.Basic;
using WGShare.API.Helpers;
using WGShare.API.Hubs;
using WGShare.Domain.Constant;
using WGShare.Domain.DTOs.Login;
using WGShare.Domain.Entities;
using WGShare.Domain.FriendlyException;
using WGShare.Domain.FriendlyException.Exceptions;
namespace WGShare.API.Controllers
{
[ApiExplorerSettings(GroupName = "public")]
[Route("auth")]
public class AuthController : BasicController
{
private readonly ISqlSugarClient _sqlSugar;
private readonly JwtHelper _jwtHelper;
private readonly IConfiguration _configuration;
private readonly IHubContext<SessionManageHub, IMessageClient> _hubContext;
public AuthController(ISqlSugarClient sqlSugar, JwtHelper jwtHelper,
IConfiguration configuration,
IHubContext<SessionManageHub, IMessageClient> hubContext)
{
_sqlSugar = sqlSugar;
_jwtHelper = jwtHelper;
this._configuration = configuration;
this._hubContext = hubContext;
}
/// <summary>
/// 检查用户名
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
[HttpGet("check-user"), AllowAnonymous]
public async Task<bool> CheckUser([FromQuery] string account)
{
return await _sqlSugar.Queryable<User>().AnyAsync(x => x.IsDelete == false && x.Account == account);
}
/// <summary>
/// 正常账号登录
/// </summary>
/// <returns></returns>
[HttpPost("login"), AllowAnonymous]
public async Task<IActionResult> Login([FromBody] UserLoginDTO loginDTO)
{
var user = await _sqlSugar.Queryable<User>()
.FirstAsync(x => x.Account == loginDTO.Account && x.IsDelete == false && x.Pwd == loginDTO.Pwd);
if (user == null)
{
throw Oops.Oh("用户名或密码不正确!");
}
var tenant = await _sqlSugar.Queryable<Tenant>().FirstAsync(x => x.Id == user.TenantId);
if (tenant == null || tenant.IsDelete == true)
{
throw Oops.Oh("该区域账号已停用,请联系管理员");
}
if (await _sqlSugar.Queryable<Role>().AnyAsync(x => x.IsDelete == true && x.Id == user.RoleId))
{
throw Oops.Oh("该角色账号已停用,请联系管理员");
}
var perms = await _sqlSugar.Queryable<Permission>()
.InnerJoin<RolePrem>((m, rm) => m.Id == rm.PermId)
.Where((m, rm) => rm.RoleId == user.RoleId)
.Distinct()
.ToListAsync();
user.PermValue = perms.Sum(x => x.PermValue);
user.TenantName = tenant.TenantName;
var btnAutn = new List<Claim>();
btnAutn.Add(new Claim("perm", user.PermValue.ToString()));
btnAutn.Add(new Claim("roleid", user.RoleId));
btnAutn.Add(new Claim("tenant", user.TenantId));
btnAutn.Add(new Claim("account", user.Account));
btnAutn.Add(new Claim("uname", user.UserName));
btnAutn.Add(new Claim("ssid", user.ScreenShareId));
// 强制下线
var connectId = RedisHelper.Instance.HGet(RedisKeyConstant.SessionManage.GetOnlineUserKey(user.TenantId), user.Id);
if (!string.IsNullOrWhiteSpace(connectId))
{
await _hubContext.Clients.Client(connectId).ForceLogout("账号已在其他地方登录,您被迫下线!");
}
var accessToken = _jwtHelper.CreateToken(user.Id, btnAutn);
var refreshToken = Guid.NewGuid().ToString();
using (var pipe = RedisHelper.Instance.StartPipe())
{
// 设置刷新token
pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken), user, TimeSpan.FromDays(7).TotalSeconds.ToInt32());
// 记录accessToken
pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), accessToken, _configuration["Jwt:Expires"].ToInt32());
pipe.EndPipe();
}
return Ok(new
{
perms = user.PermValue,
token = accessToken,
refresh_token = refreshToken,
roleId = user.RoleId,
userName = user.UserName,
tenantName = tenant.TenantName,
expire = _configuration["Jwt:Expires"].ToInt32(),
account = user.Account,
uid = user.Id,
screenShareId = user.ScreenShareId
});
}
/// <summary>
/// 刷新token
/// </summary>
/// <param name="refreshToken"></param>
/// <returns></returns>
[HttpPost("refresh"), AllowAnonymous]
public async Task<IActionResult> Refresh([FromQuery] string refreshToken)
{
var user = RedisHelper.Instance.Get<User>(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken));
if (user == null || string.IsNullOrWhiteSpace(user.Id))
{
throw new FriendlyInternalException("登录已失效,请重新登录", null, 1403);
}
var btnAutn = new List<Claim>();
btnAutn.Add(new Claim("perm", user.PermValue.ToString()));
btnAutn.Add(new Claim("roleid", user.RoleId));
btnAutn.Add(new Claim("tenant", user.TenantId));
btnAutn.Add(new Claim("account", user.Account));
btnAutn.Add(new Claim("uname", user.UserName));
btnAutn.Add(new Claim("ssid", user.ScreenShareId));
var accessToken = _jwtHelper.CreateToken(user.Id, btnAutn);
var refreshTokenNew = Guid.NewGuid().ToString();
using (var pipe = RedisHelper.Instance.StartPipe())
{
pipe.Del(RedisKeyConstant.Data.GetRefreshTokenKey(refreshToken));
pipe.Set(RedisKeyConstant.Data.GetRefreshTokenKey(refreshTokenNew), user, TimeSpan.FromDays(7).TotalSeconds.ToInt32());
pipe.Set(RedisKeyConstant.Data.GetAccessTokenKey(user.Id), accessToken, _configuration["Jwt:Expires"].ToInt32());
pipe.EndPipe();
}
return Ok(new
{
perms = user.PermValue,
token = _jwtHelper.CreateToken(user.Id, btnAutn),
refresh_token = refreshTokenNew,
roleId = user.RoleId,
userName = user.UserName,
tenantName = user.TenantName,
expire = _configuration["Jwt:Expires"].ToInt32(),
account = user.Account,
uid = user.Id,
screenShareId = user.ScreenShareId
});
}
/// <summary>
/// 匿名登录,直接进入会议室
/// </summary>
/// <returns></returns>
[HttpPost("anon-login"), Obsolete]
public async Task<IActionResult> Login([FromBody] AnonymousLoginDTO loginDTO)
{
var room = await _sqlSugar.Queryable<Room>().FirstAsync(x => x.Id == loginDTO.RoomId);
if (room == null)
{
throw Oops.Oh("会议号无效");
}
var anonRoleId = "2";
// 匿名登录使用普通用户身份
var perms = await _sqlSugar.Queryable<Permission>()
.InnerJoin<RolePrem>((m, rm) => m.Id == rm.PermId)
.Where((m, rm) => rm.RoleId == anonRoleId)
.Distinct()
.ToListAsync();
var tenant = await _sqlSugar.Queryable<Tenant>().FirstAsync(x => x.Id == room.TenantId);
if (tenant == null || tenant.IsDelete == true)
{
throw Oops.Oh("该区域账号已停用,请联系管理员");
}
var btnAutn = new List<Claim>();
btnAutn.Add(new Claim("perm", perms.Sum(x => x.PermValue).ToString()));
btnAutn.Add(new Claim("roleid", anonRoleId));
btnAutn.Add(new Claim("tenant", room.TenantId));
btnAutn.Add(new Claim("mac", loginDTO.Mac));
btnAutn.Add(new Claim("machine", loginDTO.MachineName));
btnAutn.Add(new Claim("nickName", loginDTO.NickName));
return Ok(new
{
perms = perms.Sum(x => x.PermValue),
token = _jwtHelper.CreateToken("0", btnAutn),
roleId = anonRoleId,
userName = loginDTO.NickName,
tenantName = tenant.TenantName
});
}
/// <summary>
/// 登出(暂未处理任何业务逻辑)
/// </summary>
/// <returns></returns>
[HttpPost("logout")]
public async Task<bool> Logout()
{
return true;
}
#region
/// <summary>
/// 管理员登录
/// </summary>
/// <returns></returns>
[HttpPost("admin/login"), AllowAnonymous]
public async Task<string> LoginForAdmin([FromBody] UserLoginDTO loginDTO)
{
var adminClient = _sqlSugar.AsTenant().GetConnection("usercenter");
var user = await adminClient.Queryable<Admin>()
.FirstAsync(x => x.Account == loginDTO.Account && x.Password == loginDTO.Pwd);
if (user == null)
{
throw Oops.Oh("用户名或密码不正确!");
}
return _jwtHelper.CreateToken(user.Id);
}
/// <summary>
/// 管理员信息
/// </summary>
/// <returns></returns>
[HttpGet("admin/info")]
public async Task<IActionResult> GetAdminInfo()
{
var adminClient = _sqlSugar.AsTenant().GetConnection("usercenter");
var user = await adminClient.Queryable<Admin>()
.FirstAsync(x => x.Id == UId);
if (user == null)
{
throw Oops.Oh("管理员不存在!");
}
return Ok(new
{
name = user.Name,
id = user.Id,
});
}
#endregion
}
}