unity使用BestHTTP插件连接到SignalR做身份验证

本文介绍了如何在Unity中利用BestHTTP插件连接到SignalR,并通过Token进行身份验证。示例代码展示了从获取Token到连接SignalR并进行身份验证的过程,同时也提到了使用Cookie验证的替代方案。
摘要由CSDN通过智能技术生成

unity使用BestHTTP插件连接到SignalR做身份验证

 最近研究了下.net core webapi,搞到SignalR时,想使用SignalR代替WebSockt(SignalR内部也是WebSockt)做一些事情。 然后通过使用BestHTTP插件连接到SignalR,并使用Token验证身份,也简单提到Cookie验证身份的方法。

public class HubManager : MonoBehaviour
{
    public string url = $" https://localhost:5001";

    private string _token;
    private HubConnection _hub;

    private async Task Start()
    {
        //StartCoroutine(GetToken1());//使用UnityWebRequest获取Token

        _token = await GetToken();//获取token
        await ConnectHubAsync(url, _token);//连接SignalR
    }

    // BestHTTP请求获取Token
    // 也可以放在IAuthenticationProvider接口中的StartAuthentication方法获取
    private Task<string> GetToken()
    {
        Uri uri = new Uri(this.url + "/Token/CreateToken");
        LoginRequest loginRequest = new LoginRequest("admin", "123456");
        string json = JsonMapper.ToJson(loginRequest);
        byte[] bytes = Encoding.UTF8.GetBytes(json);

        HTTPRequest request = new HTTPRequest(uri, HTTPMethods.Post);
        request.AddHeader("Content-Type", "application/json;charset=utf-8");
        request.RawData = bytes;

        return request.GetAsStringAsync();
    }

    //连接SignalR
    public async Task ConnectHubAsync(string urlStr, string token)
    {
        JsonProtocol protocol = new JsonProtocol(new LitJsonEncoder());
        _hub = new HubConnection(new Uri(urlStr + "/hub"), protocol);
        //添加token,作为身份认证(这就需要再连接前拿到token)
        //如果不使用token,就再OnConnected中添加认证(前期不成熟的方案)
        //如果使用cookie验证,可以参考SampleCookieAuthentication类改一下
        //对IAuthenticationProvider接口理解在下面
        _hub.AuthenticationProvider = new HeaderAuthenticator(token);
        _hub.OnConnected += OnConnected;
        _hub.OnError += OnError;
        _hub.OnClosed += OnClosed;
        _hub.On<string>("ReceiveMsg", ReceiveMsg);//接收信息
        await _hub.ConnectAsync();//需要连接
        await PublicChat("Hi");

        //_hub.NegotiationResult.AccessToken = _token;
    }

    //使用UnityWebRequest获取Token
    private IEnumerator GetToken1()
    {
        //https://localhost:7296/Token/CreateToken
        string urlStr = this.url + "/Token/CreateToken";
        LoginRequest loginRequest = new LoginRequest("admin", "123456");
        string json = JsonMapper.ToJson(loginRequest);
        byte[] bytes = Encoding.UTF8.GetBytes(json);

        UnityWebRequest request = new UnityWebRequest()
        {
            url = urlStr,
            method = UnityWebRequest.kHttpVerbPOST,
            uploadHandler = new UploadHandlerRaw(bytes),
            downloadHandler = new DownloadHandlerBuffer()
        };
        request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
        yield return request.SendWebRequest();
        if (request.result != UnityWebRequest.Result.Success)
        {
            Debug.Log(request.error);
        }
        else
        {
            _token = request.downloadHandler.text;
            Debug.Log(_token);
        }
    }

    // 群聊
    public async Task PublicChat(string msg)
    {
        //ReceiveMsg 为SignalR为接收信息的方法名
        await _hub.SendAsync("ReceiveMsg", msg);
    }

    // 私聊
    public async Task PrivateChat(int id, string msg)
    {
        await _hub.SendAsync("PrivateChat", id, msg);
    }

    // 接收消息
    private void ReceiveMsg(string msg)
    {
        Debug.Log($"Hub -> {msg}");
    }

    // hub关闭时调用
    private void OnClosed(HubConnection connection)
    {
        Debug.Log("Hub -> 与服务端断开连接...");
    }

    // hub异常
    private void OnError(HubConnection connection, string error)
    {
        Debug.LogError($"Hub -> {error}");
    }

    // Hub连接成功
    private void OnConnected(HubConnection connection)
    {
        Debug.Log("Hub -> 与服务端建立连接...");
        // 身份认证,不使用token或cookie时用的
        // connection.SendAsync("AddConnected", 1, "gzhen");
    }

}

public record LoginRequest
{
    public string Username { private set; get; }
    public string Password { private set; get; }
    public LoginRequest(string username, string password)
    {
        Username = username;
        Password = password;
    }
}

.net core webapi 发布Token代码

[HttpPost]
public ActionResult<string> CreateToken(LoginRequest request)
{
    if (request.Username.Equals("admin") && request.Password.Equals("123456"))
    {
        //添加token
        List<Claim> claims = new();
        claims.Add(new Claim(ClaimTypes.NameIdentifier, "1"));//id
        claims.Add(new Claim(ClaimTypes.Name, "admin"));//名字
        claims.Add(new Claim(ClaimTypes.Role, "admin"));//角色

        byte[] keyBytes = Encoding.UTF8.GetBytes(_tokenSetting.Value.SecKey);
        DateTime expire = DateTime.Now.AddSeconds(_tokenSetting.Value.ExpireSeconds);//超时时间

        SymmetricSecurityKey key = new(keyBytes);
        SigningCredentials credentials = new(key, SecurityAlgorithms.HmacSha256Signature);
        JwtSecurityToken token = new(claims: claims, expires: expire, signingCredentials: credentials);

        string tokenStr = new JwtSecurityTokenHandler().WriteToken(token);
        return Ok(tokenStr);
    }
    else
    {
        return BadRequest();
    }
}

SignalR 验证身份代码

public class NotificationHub : Hub
{
    private static readonly List<User> users = new List<User>();

    private readonly ILogger<NotificationHub> _logger;

    public NotificationHub(ILogger<NotificationHub> logger)
    {
        _logger = logger;
    }
    public override Task OnConnectedAsync()
    {
        //_logger.LogInformation($"与[{Context.ConnectionId}]建立连接...");

        //使用token作为身份认证
        string id = Context.User.FindFirstValue(ClaimTypes.NameIdentifier);
        string name = Context.User.FindFirstValue(ClaimTypes.Name);
        _logger.LogInformation($"与[id:{id} username:{name}]建立连接...");
        User user = new User(int.Parse(id), name, Context.ConnectionId);
        users.Add(user);
        return base.OnConnectedAsync();
    }
}

IAuthenticationProvider接口理解

此接口使用来做身份认证的接口,HeaderAuthenticator和SampleCookieAuthentication都继承此接口,也可以根据这两个类理解的此接口。

public interface IAuthenticationProvider
{
    /// <summary>
    /// 是否对开启身份认证
    /// </summary>
    bool IsPreAuthRequired { get; }

    /// <summary>
    /// 身份认证的成功的回调,如果IsPreAuthRequired为fasle则不验证。
    /// </summary>
    event OnAuthenticationSuccededDelegate OnAuthenticationSucceded;

    /// <summary>
    /// 身份认证的失败的回调
    /// </summary>
    event OnAuthenticationFailedDelegate OnAuthenticationFailed;

    /// <summary>
    /// 开始验证,如果IsPreAuthRequired则不调用。
    /// 可以获取token,cookie等信息的操作可以搬到在此处
    /// </summary>
    void StartAuthentication();

    /// <summary>
    /// 准备请求,将得到的token,cookie等数据在此处做整理。
    /// </summary>
    void PrepareRequest(HTTPRequest request, RequestTypes type);
 }

 完结散花。欢迎来讨论,提出意见。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值