How to POST data to a URL from NestJs code? - post

I have a login form with username and password. I'm trying to validate these credentials using the Nest Js authentication strategy here. So in the corresponding auth.service.ts file, I'm using "nativescript core modules http" to do a POST request to OAuth URL to validate credentials . But this doesn't work:
import { Injectable } from '#nestjs/common';
import { request } from "tns-core-modules/http";
const OAUTH_URL = 'url';
#Injectable()
export class AuthService {
async validateUser(username: string, password: string): Promise<any> {
let data = new FormData();
data.set('client_id', 'sb-nestjs-app!t36258');
data.set('client_secret', 'XrHuBRhyvuVNYNJNHlWLgcuBIyc=');
data.set('username', username);
data.set('password', password);
data.set('grant_type', 'password');
data.set('response_type', 'token');
request({
url: OAUTH_URL,
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json;charset=utf8"
},
content: data
}).then((response) => {
console.log('response => ' + response + ' statuscode ' + response.statusCode);
if (response.statusCode == 200) {
const token = response.content['access_token'];
//TODO:
// need to send scope also
return token;
}
}, (e) => {
console.log('error' + e);
return null;
});
return null;
}
}
When I run 'nest start' after above code in place, I receive Error: Cannot find module './http-request'
I'm not sure what is going here, I tried "npm install http-request" it didn't work either. Basically, I need to POST credentials to a OAuth url in NestJs. Any guidance? Thank you.

Try with HttpModule from NestJS.
Also you can try request from npm, but they deprecated this package. From what I saw on their discussion, the package still works but you will not have support for it, or anything. Here are some alternatives to it .
I'm not sure you are using the correct request npm module. I'm talking about:
import { request } from "tns-core-modules/http"
Good Luck!

Related

Custom response headers not send with 404 status code, ASP.NET MVC

I have an API controller (.NET Framework 4.8 and IIS server) that returns a file or 404 if the file is not found. I added some custom headers to the response just to specify what was the problem (I'm than using this information on FE app to show some specifying messages to user).
However, when I call the API, I don't get the custom headers when returning 404. I tried changing the status code to 200, 204 and it works.
The controller method looks like this:
[HttpPost]
public ActionResult FileDownload(DataModel data)
{
try
{
return DownloadFile(data);
}
catch
{
}
Response.Headers.Add("x-custom-header", "custom header content");
return new HttpStatusCodeResult(404);
}
The FE method for fetching the file:
fetch(props.href)
.then((response) => {
let customHeader= response.headers.get("x-custom-header");
console.log(customHeader);
if (response.status !== 200) {
throw response.status;
}
return response.blob();
})
.then((blob: Blob) => {
let fileUrl: string = window.URL.createObjectURL(blob);
let a: HTMLAnchorElement = document.createElement("a");
a.href = fileUrl;
a.download = fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
setLinkText(linkTextSuccess);
})
.catch((error) => {
console.log(error);
setLinkText(linkTextError);
});
Why is it that with 404 status code, the headers are not sent? Could I somehow enforce that?
Thank you for your time!

Add a Bearer Token to a Breezejs fetchMetadata Call

My breeze services works great. But I just moved it behind a WSO2 API Manager. It now needs a Bearer Token for each call.
I have the Bearer Token. But I can't seem to figure out how to add it to the Metadata Call.
I tried something like this. But it did not add a header to the metadata call:
var ajaxAdapter: any = breeze.config.getAdapterInstance('ajax');
ajaxAdapter.defaultSettings = {
headers: {
"X-Test-Header": "foo2"
}
}
Does the fetchMetadata use a different system from the ajax adapter?
How can I add a header to the Fetch Metadata call?
Turns out I was using the Fetch API. So I had to do it that way. Here is what my setup looks like:
setupFetchClient() {
let httpClient = new HttpClient();
httpClient.configure(config => {
config.withDefaults({
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
}
})
.withInterceptor({
request(request: Request) {
let accessToken = getAccessToken();
request.headers.append('Authorization', 'Bearer ' + accessToken);
return request;
},
responseError(error) {
return error;
}
})
.useStandardConfiguration();
});
// Aurelia Specific Code.
Container.instance.registerInstance(HttpClient, httpClient);
}

How to pass 3 argument to backend with `POST` request?

According to backend, I require to pass 3 argument through post request, this backend function is:
public ResponseModel Post([FromBody] CourseFileUpload item, string fileName, Stream fileToUpload)
now I am trying to pass the argument like this:
uploadFile(uploadData:ModelToFileSteam):Observable<ModelToFileSteam> {
const fileName = uploadData.fileName;
console.log('file name is', fileName);
const headers = new HttpHeaders({ 'Content-Type': 'application/json', 'Access-Control-Allow-Origin':'*' });
return this.http.post<ModelToFileSteam>(environment.baseUrl+`CourseFileUpload`, uploadData.fileToUpload, uploadData.fileName, uploadData.uploadStream)
.pipe(
map(data => {
return data;
} ),
catchError(this.handleError)
)
}
But getting error, not able to pass 3 arguments at all. what is the correct way to do this?
any one help me?
I will suggest wrapping all in a single object. And send it to backend.
Or just send uploadData
return this.http.post<ModelToFileSteam>(environment.baseUrl+`CourseFileUpload`, uploadData)
.pipe(
map(data => {
return data;
} ),
catchError(this.handleError)
)
And in the backend, you can get uploadDate like req.body.uploadData
To check you can console.log(uploadData.fileName);
its my working example
this.http.post<Customer>(this.base_url + 'v1/customers', client, this.getHeaders());
Where client is customer object and this.getHeaders() is:
getHeaders() {
return {
headers: new HttpHeaders({
'Content-Type': 'application/json; charset=utf-8',
})
};
}
Good luck!

Google OAuth Issue

I have a Umbraco website that has google sign in button configured as follows:
At the top of the page (inside the header section) I have the scripts for calling google API:
<script src="https://apis.google.com/js/client:platform.js?onload=start" async defer></script>
<script>
function start() {
gapi.load('auth2', function() {
auth2 = gapi.auth2.init({
client_id: '<myapp client Id>.apps.googleusercontent.com',
// Scopes to request in addition to 'profile' and 'email'
redirect_uri: 'http://localhost:40136/umbraco/Surface/AuthSurface/GoogleAuthrizedUser',
scope: 'profile email'
});
});
}
</script>
In the body section of the code I have the google button setup and associated click function:
<script>
function onSignIn(authResult) {
if (authResult['code']) {
var authCode = authResult['code'];
console.log("Authorization Code: " + authCode);
$.post("/umbraco/Surface/AuthSurface/GoogleAuthrizedUser", { code: authCode })
.done(function(msg) {
// Success settings
})
.fail(function(xhr, status, error) {
});
} else {
//authResult['code'] is null
//handle the error message.
}
};
</script>
Controller code that handles the call back on the server end:
public class AuthSurfaceController : SurfaceController
{
public ActionResult GoogleAuthrizedUser()
{
string AuthCode = HttpContext.Request["code"];
var info = new GoogleAccessTokenResponse();
var client = new GoogleOAuthClient();
try
{
info = client.GetAccessTokenFromAuthorizationCode(AuthCode);
}
catch (Exception ex)
{
var strMessage = String.Format("<div class=\"info\"><p>{0}</p><p>{1}</p></div>", "Google Login Error",
ex.Message);
return Json(new AjaxOperationResponse(false, strMessage));
}
}
}
On the Serverside I am using Skybrud Social plugin for accessing google apis.
The google authentication happens in the popup and authorizes client with credentials and authResult['code'] has a valid code.
In the controller when I initialize the client and call the function GetAccessTokenFromAuthorizationCode(AuthCode), it returns an exception of 'Invalid Request'
I tried checking this authResult['code'] returned in the javascript function onSignIn in the https://developers.google.com/oauthplayground/
Same error description is shown 'Invalid request'. I am not sure why this is happening. The error returned is "invalid_grant"
Can anyone have a solution to this problem? What am I doing wrong here?
In your surface controller you're initializing a new instance of GoogleOAuthClient, but without setting any of the properties. The GetAccessTokenFromAuthorizationCode method requires the ClientId, ClientSecret and RedirectUri properties to have a value. You can initialize the properties like this:
// Initialize a new instance of the OAuth client
GoogleOAuthClient oauth = new GoogleOAuthClient {
ClientId = "The client ID of your project",
ClientSecret = "The client secret of your project",
RedirectUri = "The return URI (where users should be redirected after the login)"
};
You can read more about authentication in the documentation: http://social.skybrud.dk/google/authentication/ (the approach explained there will however not use any JavaScript)

WebApi 2 + Owin Use urlencoded body on token request

In my WebAPI2 app I use OAuth authentication through Owin middleware. In order to get token client should use application/x-www-form-urlencoded body in request.
function userAccount($resource, appSettings) {
return {
registration: $resource(appSettings.serverPath + "/api/Account/Register", null,
{
'registerUser' : { method : 'POST'}
}
),
login : $resource(appSettings.serverPath + "/Token", null,
{
'loginUser': {
method: 'POST',
headers: {
'Content-Type' : 'application/x-www-form-urlencoded'
},
transformRequest: function (data, headersGetter) {
var str = [];
for (var d in data) {
str.push(encodeURIComponent(d) + "=" + encodeURIComponent(data[d]));
}
return str.join("&");
}
}
}
)
}
}
But is there any method to override this behaviour to use raw body in json format? Instead of this: "grant_type=password&username=user&password=123456" want to use this: "{ grant_type: "password", username:"user", password="123456" }".
Appreciate any suggests.
You could set up an action in a controller as a "proxy" method that could accept the json in the body and then call the internal method with the url encoded parameters.

Resources