Perry J
Perry J

Reputation: 365

How to get jwt token from NodeJs to .NET app?

What is the best way to get a jwt token from a running NodeJS server, in a C# .NET Windows app? in .NET I use HttpClient to connect to an oauth2 server (and that succeeds), but how to get the very jwt token?

In 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}`)
})

This is working. I am getting the "Eureka!", in Postman as well as in my .NET HttpClient call

In my console I am getting (x-ing original info...), (output from console.log(response.data);)

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

So, in my C# code I do this (also getting "Eureka!", I see it in the 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();
    }

But how to get the very token?

Upvotes: 0

Views: 495

Answers (1)

B. Lec
B. Lec

Reputation: 352

In NodeJS you never send the token result in the api response, modify it like this :

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());
})

In 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;
}

Or just don't use node js and do everything in 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");
}

Upvotes: 1

Related Questions