C# 限制单设备登录实现

发布于 27 天前  56 次阅读


1.建立个中间件并封装验证方法

2.验证方法封装如下(本方法已经包含token检测)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Models;
using static System.Net.Mime.MediaTypeNames;

namespace common.Utils
{
    public class JwtValidateUser(RequestDelegate next,IRedisHelper _redisHelper)
    {
        //private readonly RequestDelegate _nex = next;
        //白名单接口
        private string[] whiteList = ["/api/User/userLogins", "/api/User/regsiter", "/api/User/UpdatePassword"];
        private readonly JwtHelper _JwtHelper = new JwtHelper();
        public async Task InvokeAsync(HttpContext context)
        {
            //检查是否在接口白名单内
            if (whiteList.Contains(context.Request.Path.Value))
            {
                await next(context);
                return;
            }
            //检查请求头是否携带token
            if (!context.Request.Headers.ContainsKey("Authorization"))
            {
                context.Response.StatusCode = 401;
                await context.Response.WriteAsync("你无权访问该接口");
                return;
            }
            //从请求头获取token
            var token = context.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
            //解析token 的值
            ClaimsPrincipal claimsPrincipal = _JwtHelper.JwtDecrypt(token);
            // 获取用户名称
            var username = claimsPrincipal.FindFirst("name")?.Value;
            //获取用户UUID
            var uuid = claimsPrincipal.FindFirst("jti")?.Value;
            //检查数据库内用户是否存在 
            if (await DbScope.GetConnect("mysql_test_aliyun").Queryable<user_info>().Where(x=>x.username == username).FirstAsync()!=null)
            {
                //用户存在后查询token 并解密 对比唯一UUID UUID 对不上返回登录失败
                string userTokens = await _redisHelper.GetStringAsync(username);
                if(userTokens == null)
                {
                    context.Response.StatusCode = 401;
                    await context.Response.WriteAsync("用户登陆信息过期!!!");
                    return;
                }
                //解析token
                ClaimsPrincipal userClaim = _JwtHelper.JwtDecrypt(userTokens);
                if(userClaim.FindFirst("jti")?.Value == uuid)
                {
                    context.User = userClaim;
                    await next(context);
                }
                else
                {
                    context.Response.StatusCode = 401;
                    await context.Response.WriteAsync("当前用户已在别处登陆!!!");
                    return;
                }
            }
            else
            {
                context.Response.StatusCode = 401;
                await context.Response.WriteAsync("当前用户不存在!!");
                return;
            }
        }
    }
}

2.在program内注册中间键

app.UseMiddleware(); //注册中间件

一个练习时长还差一年半的切图仔,有需求可联系 QQ:963827384
最后更新于 2025-09-23