【问题标题】:How to get jwt token from NodeJs to .NET app?如何从 NodeJs 获取 jwt 令牌到 .NET 应用程序?
【发布时间】:2021-08-26 08:07:05
【问题描述】:

在 C# .NET Windows 应用程序中,从正在运行的 NodeJS 服务器获取 jwt 令牌的最佳方式是什么? 在 .NET 中,我使用 HttpClient 连接到 oauth2 服务器(并且成功),但是如何获得非常 jwt 令牌?

在 NodeJS 中:

const express = require('express')
const https = require('https');
const axios = require('axios');
var url = require('url');
const app = express()
const port = 3000
const agent = new https.Agent({ rejectUnauthorized: false });

async function get_token() {
    try {
        let url = "https://oauthservername/token.oauth2";
        let formfields = "client_id=cid&grant_type=password&validator_id=ourAuthNG&client_secret=secretstring&username=billy&password=xxxxxxxxx";
        let response = await axios.post(url, formfields,  { httpsAgent: agent });
        console.log(response.data);
    } catch (error) {
        console.log(error);
    }
}

app.get('/token', (req, res) => {
get_token();
res.send('Eureka!');

})


app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
})

这是有效的。我在 Postman 以及我的 .NET HttpClient 调用中得到了“Eureka!”

在我的控制台中,我得到了(x-ing 原始信息...),(console.log(response.data) 的输出;)

{
    access_token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    refresh_token: 'xxxxxxxxxxxxxxxxx',
    token_type: 'Bearer',
    expires_in: 28799
}

所以,在我的 C# 代码中我这样做(也得到“Eureka!”,我在 responseBody 中看到它):

    private async void cmdConnectServer_Click(object sender, EventArgs e)
    {
        //client is HttpClient
        client.BaseAddress = new Uri("http://localhost:3000/");
        HttpResponseMessage response = await client.GetAsync("http://localhost:3000/token");
        response.EnsureSuccessStatusCode();
        string responseBody = await response.Content.ReadAsStringAsync();
    }

但是如何获得令牌呢?

【问题讨论】:

    标签: node.js .net axios postman


    【解决方案1】:

    在 NodeJS 中,您永远不会在 api 响应中发送令牌结果,请像这样修改它:

    async function get_token() {
        try {
            let url = "https://oauthservername/token.oauth2";
            let formfields = "client_id=cid&grant_type=password&validator_id=ourAuthNG&client_secret=secretstring&username=billy&password=xxxxxxxxx";
            let response = await axios.post(url, formfields,  { httpsAgent: agent });
            console.log(response.data);
            //Return the oauth2 result
            return response.data;
        } catch (error) {
            console.log(error);
        }
    }
    
    app.get('/token', (req, res) => {
        //sending 'Eureka!' is pointless, instead send the token result
        res.send(get_token());
    })
    

    在c#中

    using System;
    using System.Runtime.Serialization;
    using System.Text.Json;
    
    ... ...
    
    //Class for response deserialization
    [Serializable]
    public class TokenResult
    {
        [DataMember]
        public string access_token { get; set; }
    
        [DataMember]
        public string refresh_token { get; set; }
    
        [DataMember]
        public string token_type { get; set; }
    
        [DataMember]
        public long expires_in { get; set; }
    }
    
    private async void cmdConnectServer_Click(object sender, EventArgs e)
    {
        //client is HttpClient
        client.BaseAddress = new Uri("http://localhost:3000/");
        HttpResponseMessage response = await client.GetAsync("http://localhost:3000/token");
        response.EnsureSuccessStatusCode();
        string responseBody = await response.Content.ReadAsStringAsync();
        // Deserialize the token response and get access_token property
        string token = JsonSerializer.Deserialize<TokenResult>(responseBody ).access_token;
    }
    

    或者干脆不使用node js,用c#做所有事情

    using System;
    using System.Runtime.Serialization;
    using System.Text.Json;
    
    ... ...
    
    //Class for response deserialization
    [Serializable]
    public class TokenResult
    {
        [DataMember]
        public string access_token { get; set; }
    
        [DataMember]
        public string refresh_token { get; set; }
    
        [DataMember]
        public string token_type { get; set; }
    
        [DataMember]
        public long expires_in { get; set; }
    }
    
    public string get_token()
    {
        HttpClientHandler OpenBarHandler = new HttpClientHandler { ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator };
        HttpClient _httpClient = new HttpClient(OpenBarHandler);
        _httpClient.BaseAddress = new Uri("https://oauthservername/token.oauth2");
    
        HttpRequestMessage mess = new HttpRequestMessage();
        mess.Method = HttpMethod.Post;
        mess.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
        Dictionary<string, string> _parameters = new Dictionary<String, String>();
        _parameters.Add("grant_type", "password");
        _parameters.Add("username", "billy");
        _parameters.Add("password", "xxxxxxxxx");
        _parameters.Add("client_id", "cid");
        _parameters.Add("client_secret", "secretstring");
        _parameters.Add("validator_id", "ourAuthNG");
    
        FormUrlEncodedContent encodedContent = new FormUrlEncodedContent(_parameters);
        encodedContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
        mess.Content = encodedContent;
    
        HttpResponseMessage response = _httpClient.SendAsync(mess).Result;
    
        if (response.IsSuccessStatusCode)
        {
            string strResp = response.Content.ReadAsStringAsync().Result;
            return JsonSerializer.Deserialize<TokenResult>(strResp).access_token;
        }
        else
            throw new Exception("Token retrieval failed");
    }
    

    【讨论】:

    • 非常感谢您对此的出色回答。我在添加对 System.Text.Json 的引用时遇到了一些困难,但我想我会解决的。我会回来的!
    • 嗯...我现在对较新的 System.Text.Json 有一些问题,但是我可以安装 Newtonsoft.Json。我还可以使用您的 Tokenresult 课程吗?它们应该非常相似..
    • 是的,可以和newtonsoft一起使用JsonConvert.DeserializeObject&lt;TokenResult&gt;(strResp);
    • 还有一些问题,数据从来没有像看起来那样发送,responseBody 是空的,即使在 Postman 中,也可能是 bodyparser 的东西
    • 问题应该出在服务器端,试试res.setHeader('Content-Type', 'application/json'); res.json(get_token());
    猜你喜欢
    • 2018-06-16
    • 2017-06-22
    • 2018-01-18
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 2021-04-20
    • 2017-06-29
    • 2016-11-13
    相关资源
    最近更新 更多