Javascript: Failed to load resource: using a web API consuming gRPC Services - javascript

I have trouble using Web Api, Javascript and gRPC Services...
First of all I recommend check this question to understand what I'm doing
Calling gRPC services through a Web API in .NET 6
Problem:
This is my controller:
public class AuthController : ControllerBase
{
private readonly ILogger<AuthController> _logger;
private readonly IConfiguration _config;
private readonly UserAuthClient _userClient;
public AuthController(ILogger<AuthController> logger, IConfiguration config)
{
_logger = logger;
_config = config;
_userClient = UserAuthServiceClientHelper.GetUserServiceClient(_config["RPCService:ServiceUrl"]);
}
[HttpPost("register")]
public async Task<ActionResult<NewUserResponse>> Register([FromBody] NewUserRequest user)
{
_logger.Log(LogLevel.Debug, "Request Received for AuthController::Register");
var results = await _userClient.AddUserAsync(user);
_logger.Log(LogLevel.Debug, "Sending Response from AuthController::Register");
return Created(string.Empty, results);
}
}
And this is Javascript code fetch
function registerJS() {
const register = document.getElementById('register');
const nome = document.getElementById('nome');
const email = document.getElementById('email');
const pass = document.getElementById('pass');
const item = {
Username: nome.value.trim(),
Email: email.value.trim(),
Password: pass.value.trim()
};
// api = 'api/Auth/register'
fetch(uri, {
//credentials: 'include',
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(item)
})
.then(response => {
debugger;
if (response.status == 200) {
return response.json();
} else {
window.alert('Error, Motivo:' +
response.statusText());
throw new Error(response.status);
return;
}
})
.then((res) => {
debugger;
nome.value = '';
email.value = '';
pass.value = '';
window.alert('Successful Registration');
document.getElementById('LoginCheck').click();
})
.catch(error => {
debugger;
if (error.status == 400) {
window.alert('Bla Bla Bla 400_2) Register:' + error.statusText);
throw new Error(error.status);
return;
} else if (error.status == 401) {
window.alert('Bla Bla Bla 401_2) Register:' + error.statusText);
throw new Error(error.status);
return;
} else {
window.alert('It is not possible to register, Username or email already used
in the application');
throw new Error(error.status);
return;
}
});
}
So I'm calling a function of the web api (this is use gRPC Service method) with the fetch but it gives me error 404 idk why,
I test the method without the gRPC (simple web api using EF and javascript) and also test the gRPC service in console (both works fine) and now I want to use both same time and fails
I run first the gRPC server and next the web api
Also I don't know if the error can be because of the dll files but I need help because I think everything I implement its ok (rebuild gives me 0 errors)
Any help is welcome and sry if my english is bad

Related

How to improve sequential promises execution and force fulfillment

This code is being used in a Sveltekit web application.
In the first step I get a user jwt token from an api like : dashboard.example.com/auth/local
and in the second step I'm using the response of the first api call to get full information from an api endpoint like this : example.com/api/users/token
This is an endpoint in an Sveltekit application:
import { json as json$1, error } from '#sveltejs/kit';
import axios from 'axios';
import md5 from 'md5';
import { SITE_ADDRESS } from '$lib/Env';
let userToken;
/** #type {import('#sveltejs/kit').RequestHandler} */
export async function POST({ request }) {
const bodyData = await request.json();
let identifier = bodyData.data.identifier;
let password = bodyData.data.password;
let loginToken = bodyData.data.loginToken;
let newLoginToken = md5(identifier + password + process.env.SECURE_HASH_TOKEN);
let dataResult = await axios
.post(`${import.meta.env.VITE_SITE_API}/auth/local`, {
identifier: identifier,
password: password
})
.then((response) => {
return response.data;
})
.then((response) => {
let userSummaryData = response;
userToken = md5(
userSummaryData.user.username + userSummaryData.user.id + process.env.SECURE_HASH_TOKEN
);
let userCompleteData = axios
.post(`${SITE_ADDRESS}/api/users/${userToken}`, {
data: {
userID: userSummaryData.user.id,
username: userSummaryData.user.username
}
})
.then((response) => {
return {
userJWT: userSummaryData.jwt,
userSummary: userSummaryData.user,
userFullSummary: response.data.userFullSummary
};
});
return userCompleteData;
})
.catch((error) => {
// console.log(' ---- Err ----');
});
if (dataResult && newLoginToken == loginToken) {
return json$1(
{
userJWT: dataResult.userJWT,
userSummary: dataResult.userSummary,
userFullSummary: dataResult.userFullSummary
},
{
headers: {
'cache-control': 'private, max-age=0, no-store'
}
}
);
} else if (dataResult && newLoginToken != loginToken) {
throw error(400, 'Something wrong happened');
}
throw error(401, 'Something wrong happened');
}
This code is work perfectly in localhost. But when I test it on host I get error 401.
and the question is :
Why this works on localhost but doesn't work on the server?
How can I improve this kind of promises (I'd like to use the response of the first api call in the second api call and return both
as a result)

Compress request body to send to PHP webserver

I have a Angular application which makes post request like the following:
async syncDataWithMaster(): Promise<AxiosResponse<any> | void> {
....
const jsonData = {
lastSyncTimeStamp,
deviceID,
userUUID,
lData,
aData,
aiData,
fData,
oData,
caData,
};
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded/json/gzip';
axios.defaults.headers.post.Authorization = token;
const url = this.endpoint + 'syncData.php';
return axios.post(url, jsonData, {
onUploadProgress: progressEvent => {console.log('uploading')},
onDownloadProgress: progressEvent => {console.log('downloading')}
}).then((response) => {
if (response.data.status == 'success') {
return response;
} else {
throw new Error('Could not authenticate user');
}
});
} catch (e) {
}
return;
}
Usually this is fine for most of my user however some users have data up to 15-30mb. I am wondering if it possible to compress the data and send it to my PHP webserver which can then be decoded so that the upload is quicker?
Maybe consider using a compression library (depending on the content of the body). It looks like fflate can do this.

coverting javascript to python

I have a yale smart alarm and come across the the below javascript that allows you to access the alarm to get the status and set it. I'm wanting to use this in my home assistant set to which uses python.
const fetch = require('node-fetch');
const setCookie = require('set-cookie-parser');
const urls = {
login: 'https://www.yalehomesystem.co.uk/homeportal/api/login/check_login',
getStatus: 'https://www.yalehomesystem.co.uk/homeportal/api/panel/get_panel_mode',
setStatus: 'https://www.yalehomesystem.co.uk/homeportal/api/panel/set_panel_mode?area=1&mode=',
};
function getSessionCookie(username, password) {
let sessionCookie = null;
return fetch(urls.login, {
method: 'POST',
body: `id=${encodeURIComponent(username)}&password=${password}&rememberme=on&notify_id=&reg_id=Name`,
headers: {
'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'
},
})
.then((res) => {
sessionCookie = res.headers._headers['set-cookie'];
return res.json();
}).then(json => {
if (json.result === '0') {
return Promise.reject('Incorrect account details');
}
else {
return sessionCookie[0];
}
})
}
function getStatus(sessionCookie) {
return fetch(urls.getStatus, {
method: 'POST',
headers: {
'Cookie': sessionCookie,
},
}).then(res => res.text()).then(textResponse => {
// When initially writing this code I found if cookie payload
// was invalid I got this text response so I added this code to
// handle this, shouldn't happen but good to have an error message
// for this use case
if (textResponse === 'Disallowed Key Characters.') {
return Promise.reject('Invalid request');
}
else {
try {
// Hopefully if we got to this point we can parse the json
const json = JSON.parse(textResponse);
if (json.result === '0') {
return Promise.reject('Unable to get status');
}
else {
return json;
}
} catch (error) {
// If you get this error message I likely have not handled
// a error state that I wasnt aware of
return Promise.reject('Unable to parse response');
}
}
});
}
function setStatus (sessionCookie, mode) {
return new Promise((resolve, reject) => {
if (!sessionCookie || sessionCookie.length === 0) {
reject('Please call getSessionCookie to get your session cookie first');
}
if (mode !== 'arm' && mode !== 'home' && mode !== 'disarm') {
reject('Invalid mode passed to setStatus');
}
resolve(fetch(`${urls.setStatus}${mode}`, {
method: 'POST',
headers: {
'Cookie': sessionCookie,
},
}));
});
}
module.exports = {
getSessionCookie,
getStatus,
setStatus,
}
i'm every new to coding but was able to piece the below together to return the current status of my alarm. the problem is I'm unable to get it to work. based on the above code could someone please tell me what I'm missing, or if I'm going down the wrong rabbit hole....
import requests
import webbrowser
url = “https://www.yalehomesystem.co.uk/homeportal/api/login/check_login”
payload = {‘username’: ‘email#domaim.com’, ‘password’: ‘mypass’}
with requests.session() as s:
# fetch the login page
s.get(url, data=payload)
url1='https://www.yalehomesystem.co.uk/homeportal/api/panel/get_panel_mode'
# post to the login form
r = s.post(url1, data=payload)
print(r.text)
To add more contexts I'm getting the following error
{"result":"0","message":"system.permission_denied","code":"999"}

Angular http post failure response for http://localhost:8080/user/login: 500 OK

I have an api service which communicates with the api. It looks like this
#Injectable()
export class ApiService {
private headers = new HttpHeaders({
'Content-type': 'application/json'
});
constructor(
private http: HttpClient,
private alertService: AlertService,
private router: Router
) { }
public credentialsLogin(request: UserCredentialsRequest) {
console.log(JSON.stringify(request));
return this.http
.post(API_URL+"/user/login", JSON.stringify(request), {headers: this.headers})
.map(
(response) => {
this.handleResponseMessages(response);
return response;
}
).catch((response) => this.handleError(response));
}
private handleResponseMessages(response:any) {
console.log(response.headers);
const messages: [{messageContent, messageType}] = response.messages;
if(messages != null && messages.length > 0) {
this.alertService.parseAlerts(messages);
}
}
private handleError (response: Response | any) {
console.log(response);
if(response != null && response.error != null) {
const error = response.error;
if(error.messages != null && error.messages.length > 0) {
const errorMessages = error.messages;
this.alertService.parseAlerts(errorMessages);
}
}
//this.router.navigate(['../']);
return Observable.throw(response);
}
}
The userservice from where I call the api service
#Injectable()
export class UserService{
activeUser: UserModel;
constructor(private api: ApiService) { }
credentialsLogin(data:{username, password}) {
console.log(data);
const request = new UserCredentialsRequest(data.username, data.password);
this.api.credentialsLogin(request)
.subscribe(
(response) => {
console.log(response);
}
);
}
}
I call the credentialsLogin user service method from component where I just pass data from the form. I think I do not need to paste component code here, that logic works just fine according to the console of objects passing to api.
When I call the credentialsLogin with proper object (it contains just username and password as string) I get the http failure response for http://localhost:8080/user/login: 500 OK error.
The bug must be in the angular. Cause when I copy the JSON.stringify(request) to the Restlet Client in my browser and send post request with that data, I get the proper answers (success login, no data sent, invalid username or password).
Does anybody where should be the mistake?

Calling Identity Server Token EndPoint

I want to call the Token Endpoint of IdentityServer 4 from my React App (running on http://localhost:3000). So in some login method I am doing:
login = () => {
const userdata = {
username: 'admin',
password: 'admin',
};
const dataForBody = `${'client_id=js&'}${'grant_type=password&' +
'username='}${encodeURI(userdata.username)}&` +
`password=${encodeURI(userdata.password)}&` +
`scope=${encodeURI('api1')}`;
const messageHeaders = {
'Content-Type': 'application/x-www-form-urlencoded',
};
axios({
method: 'post',
url: 'http://localhost:5000/connect/token',
headers: messageHeaders,
data: dataForBody,
})
.then((response) => {
console.log(response);
});
}
Now I am getting the following response:
{"error":"unauthorized_client"}
My IdSrv set up is something like the js application sample.
config.cs
namespace QuickstartIdentityServer
{
public class Config
{
// scopes define the API resources in your system
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("api1", "My API")
};
}
// client want to access resources (aka scopes)
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "js",
ClientName = "JavaScript Client",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
RedirectUris = { "http://localhost:3000/login" },
AllowedCorsOrigins = { "http://localhost:3000" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
}
}
};
}
public static List<TestUser> GetUsers()
{
return new List<TestUser> {
new TestUser {
SubjectId = "1", Username = "admin", Password = "admin"
},
};
}
}
}
startup.cs
namespace QuickstartIdentityServer
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// configure identity server with in-memory stores, keys, clients and scopes
services.AddIdentityServer()
.AddTemporarySigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetUsers());
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(LogLevel.Debug);
app.UseDeveloperExceptionPage();
app.UseIdentityServer();
}
}
}
Am I missing something?
The problem is in the client definition:
AllowedGrantTypes = GrantTypes.Implicit,
is not correct. We have to use instead:
AllowedGrantTypes = ResourceOwnerPassword
The immediate problem that jumps out is that you are attempting to authenticate with the token service by passing the username and password as URL parameters. The client's username and password should be passed in using a standard basic authorization header:
Authorization: Basic Base64Encode(myusername:mypassword)
Which for this example would end up looking like this:
Authorization: Basic bXl1c2VybmFtZTpteXBhc3N3b3Jk

Categories

Resources