Angular 5; asp.net web api http.delete doesn't work - asp.net-web-api

I have asp.net web api server run in debug made and separate project uses Angular 5 - 5.2.11.
I try to delete data and I can't, but when I use postman it work.
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '#angular/common/http';
import { Observable } from 'rxjs/Observable';
import { map } from 'rxjs/operators';
#Injectable()
export class UserService { private getUserSucess: any;
private _headers = {
headers: new HttpHeaders().set('Content-Type', 'application/json')
};
private headers={
headers: new HttpHeaders({
'Content-Type': 'application/json'
});
}
constructor(private http: HttpClient) { }
deletUserHttp() {
return this.http.delete( 'http://localhost:52817/api/users/1' ).subscribe(deleteSucess.bind(this), deleteError.bind(this));
function deleteSucess(resp) {
debugger;
return resp;
}
function deleteError(resp) {
//resp = HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: null, ok: false,
debugger;
return resp;
}
}
I also try with: this._headers and this.headars the result was the same:
HttpErrorResponse { headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: null, ok: false,
405 Method Not Allowed:
Request URL: http://localhost:52817/api/users/1
Request Method: OPTIONS
Status Code: 405 Method Not Allowed
Remote Address: [::1]:52817
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Allow: GET,PUT,DELETE
Cache-Control: no-cache
Content-Length: 71
Content-Type: application/json; charset=utf-8
Date: Sat, 16 Jun 2018 05:43:07 GMT
Expires: -1
Pragma: no-cache
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
X-SourceFiles: =?UTF-8?B?
QzpcVXNlcnNcQmV0bWlyYVxzb3VyY2VccmVwb3NcVXNlcnNcVXNlcnNcYXBpXHVzZXJzXDE=?=
Accept: /
Accept-Encoding: gzip, deflate, br
Accept-Language: pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7,de;q=0.6
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: DELETE
Connection: keep-alive
Host: localhost:52817
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
web.config:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
<rewrite>
<outboundRules>
<clear />
<rule name="AddCrossDomainHeader">
<match serverVariable="RESPONSE_Access_Control_Allow_Origin" pattern=".*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{HTTP_ORIGIN}" pattern="(http(s)?://((.+\.)?domain1\.com|(.+\.)?domain2\.com|(.+\.)?domain3\.com))" />
</conditions>
<!--<match serverVariable="RESPONSE_Access-Control-Allow-Methods" pattern="GET, POST, PUT, DELETE, OPTIONS" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{HTTP_ORIGIN}" pattern="(http(s)?://((.+\.)?domain1\.com|(.+\.)?domain2\.com|(.+\.)?domain3\.com))" />
</conditions>-->
<action type="Rewrite" value="{C:0}" />
</rule>
</outboundRules>
</rewrite>
...
Please help me because I really don't know what is wrong.

Please refer to this document for enabling CORS for your asp.net webapi. Once CORS is enabled you should be able to delete using Angular app.

Related

Nuxtjs auth not working, I am using Laravel sanctum on front end back both

I am building a web application, on the front end side I am using Nuxt js (Laravel sanctum package) and on the back end side I am using Laravel sanctum
I configure the front-end and back-end both, cookies are also generating correctly but I unable to hit the Laravel route. When I send the request it return 200 code with the cookie but Laravel method return nothing, it's means that my app is not hitting the Laravel method. After clicking on the login button I am redirected to the dashboard but console return no response with no error.
My login page headers
Request URL: http://localhost:3000/http://localhost:8000/api/admin/login
Request Method: POST
Status Code: 200 OK
Remote Address: 127.0.0.1:3000
Referrer Policy: strict-origin-when-cross-origin
Accept-Ranges: none
Connection: keep-alive
Content-Length: 2779
Content-Type: text/html; charset=utf-8
Date: Mon, 24 May 2021 16:08:05 GMT
ETag: "adb-BuJ98IeCR24JYV5bINxcPHcMBsc"
Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,la;q=0.8,mt;q=0.7,id;q=0.6,pl;q=0.5,fr;q=0.4
Connection: keep-alive
Content-Length: 2
Content-Type: application/json
Cookie: auth.strategy=laravelSanctum; auth._token_expiration.laravelSanctum=false; auth._token.laravelSanctum=false
Host: localhost:3000
Origin: http://localhost:3000
Referer: http://localhost:3000/admin/login
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"
sec-ch-ua-mobile: ?0
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36
X-Requested-With: XMLHttpRequest
Api.php
Route::prefix('admin')->group(function(){
Route::post('/login', [LoginController::class, 'login'])->name('admin.login');
});
LoginController.php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class LoginController extends Controller
{
public function login(Request $request)
{
return "Login Success";// Just for testing
}
}
nuxt.config.js
modules: [
'bootstrap-vue/nuxt',
'#nuxtjs/axios',
'#nuxtjs/auth-next'
],
auth: {
strategies: {
'laravelSanctum': {
provider: 'laravel/sanctum',
url: '/http://localhost:8000',
endpoints:{
login:{
url:'/api/admin/login',
withCredentials: true,
method: 'post',
},
logout:{
url:'admin/logout'
},
user:{
url:'/user'
},
},
user:{
property:Array
}
},
},
redirect:{
login: '/admin/login',
logout: '/',
home: '/'
}
},
Login.vue
<template>
<div>
<index />
<b-container>
<b-row>
<b-col cols="*" sm="*" md="6" lg="6" class="mx-auto mt-5 offset-2">
<b-card title="Login Page">
<b-form>
<b-form-group>
<label for="text-email">Email</label>
<b-form-input type="email" v-model="form.email" aria-describedby="email-help-block"></b-form-input>
</b-form-group>
<b-form-group>
<label for="text-password">Password</label>
<b-form-input type="password" v-model="form.password" aria-describedby="password-help-block"></b-form-input>
</b-form-group>
<b-form-group>
<b-button type="submit" #click.prevent="login()" block variant="primary">Login</b-button>
</b-form-group>
</b-form>
</b-card>
</b-col>
</b-row>
</b-container>
</div>
</template>
<script>
import index from '../index.vue'
export default {
components: { index },
data(){
return {
form:{
email: '',
password: '',
}
}
},
methods:{
async login(){
await this.$auth.loginWith('laravelSanctum', {
data: {
email: this.email,
password: this.password
}
})
.then( (response) => {
this.$router.push('/admin/dashboard')
console.log( response );
})
.catch( (error) => {
console.log( error );
})
}
}
}
</script>
package.json
"dependencies": {
"#nuxtjs/auth-next": "5.0.0-1620773067.c356fed",
"bootstrap": "^4.6.0",
"bootstrap-vue": "^2.21.2",
"core-js": "^3.9.1",
"nuxt": "^2.15.3"
},
My request URL is invalid, the spa domain added in the URL that's why my spa is not sending requests to the server.
Request URL: http://localhost:3000/http://localhost:8000/api/admin/login
TO
Request URL: http://localhost:8000/api/admin/login
That works fine.

Vuex Axios CORS Block Acess-control-allow-origin

This is the error:
So, I make sure my backend API sends the acess-control-allow-origin header:
This my axios code:
loadTopSales ({ commit }) {
axios
.get('http://tms.test/api/top-sales', {
headers: {
'Access-Control-Allow-Origin': '*',
Accept: 'application/json',
Authorization: 'Bearer ' + this.state.token,
withCredentials: true
}
})
.then(items => {
commit('SET_TOP_SALES', items)
console.log(items)
})
.catch(err => {
console.log(err)
})
}
Please, help me. I've tried every question in stackoverflow
Check curl -v -x options
My backend set header
public function handle($request, Closure $next)
{
$headers = [
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'PUT,POST,GET,OPTIONS,ORIGIN',
'Access-Control-Allow-Headers' => 'Accept,Authorization,Content-Type,Origin,X-Auth-Token',
'Access-Control-Allow-Credentials' => 'true',
];
if ($request->getMethod() === "OPTIONS") {
// The client-side application can set only headers allowed in Access-Control-Allow-Headers
return Response::make('OK', 200, $headers);
}
$response = $next($request);
foreach ($headers as $key => $value){
$response->header($key, $value);
}
return $response;
}
This my answer I config CORS in iis
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept,Authorization" />
<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, HEAD, OPTIONS" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
</httpProtocol>
Seems like the API doesn't handle CORS preflight requests. It should return Access-Control-Allow-Origin header for OPTIONS method as well (alongside Access-Control-Allow-Methods) with 204 No Content.
You can check it with curl -v -X OPTIONS http://tms.test/api/top-sale.
You can try adding proxy for your API with http-proxy-middleware. Note that this will only work for local development only.
You'll get the user guide to use http-proxy-middleware here.
For vueJS specific usage, you can try https://forum.vuejs.org/t/vue-cli-3-how-to-properly-use-http-proxy-middleware/33723

Custom log in box with Spring security and Ajax

I have a login box which is a popup on my site, I am having some issues with configuring spring security and the AJAX call to login and authenticate. I am unsure if I've set it up correctly, I'm currently getting a 401() error and reaching Critical Error of the login.js, which is unauthorized access as it stands and the /user/login method not being called.... ! Just a basic idea of how an AJAX login and authentication process should be handled in spring security would be great, including the security config.
THE HTML
<form onSubmit="login()" id="notifyMe" method="POST" role="form">
div class="form-group">
<div class="controls">
<!-- Field -->
<input type="text" id="username" name="username" placeholder="Enter your username" onfocus="this.placeholder = ''" onblur="this.placeholder = 'Click here to write your username'" class="form-control email srequiredField" />
<input type="password" id="password" name="password" placeholder="Enter your password" onfocus="this.placeholder = ''" onblur="this.placeholder = 'Click here to write your password'" class="form-control email srequiredField" />
<!-- Spinner top left during the submission -->
<i class="fa fa-spinner opacity-0"></i>
<!-- Button -->
<button id="login-btw" class="btn btn-lg submit">LOG IN</button>
<div class="clear"></div>
</div>
</div>
</form>
THE AJAX
function login() {
console.info("Attempting to authenticate");
$.ajax({
type: 'POST',
url: '/user/login',
data: $('#notifyMe').serialize(),
cache: false,
dataType: "json",
contentType: "application/json;charset=utf-8",
beforeSend:function(xhr) {
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
},
crossDomain: false,
success: function (data) {
var response = jQuery.parseJSON(data);
if (response == true) {
$(".message").html('<p class="notify-valid">Logging in...</p>').fadeIn();
window.location.reload();
console.info("Authentication Success!");
}
else {
console.error("Unable to login");
console.log(response);
$(".message").html('<p class="notify-valid">Your log in details are incorrect. Please try again.</p>').fadeIn();
}
},
error: function (data) {
console.error("Critical error");
console.log(data);
}
});
SPRING SECURITY CONFIG
#Configuration
#EnableWebSecurity
public class SpringSecurityConfigurer extends WebSecurityConfigurerAdapter{
//Used in context with custom log in form (no /j_spring_security_check)
#Autowired
private CustomAuthenticationProvider cap;
#Autowired
private AjaxAuthenticationSuccessHandler successHandler;
#Autowired
private AjaxAuthenticationFailureHandler failureHandler;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(cap);
}
#Bean(name = "requestCache")
public RequestCache getRequestCache() {
return new HttpSessionRequestCache();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
//CSS FILES AND IMAGES
.antMatchers("/fonts/**", "/css/**", "/img/**", "/js/**", "/admin/css/**", "/admin/img/**", "/admin/js/**" ).permitAll()
//PAGES FOR ALL PEOPLE
.antMatchers("/user/login", "/", "/user/**", "/register/**").permitAll()
//PAGES FOR ADMIN
.antMatchers("/admin/").access("hasAuthority('ROLE_ADMIN')")
.antMatchers("/admin/**").access("hasAuthority('ROLE_ADMIN')")
//PAGES FOR USERS
.antMatchers("/event/**").access("hasAuthority('ROLE_USER')")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/")
.loginProcessingUrl("/user/login")
.failureHandler(failureHandler)
.successHandler(successHandler)
.and()
.csrf().disable()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/user/logout"))
.logoutSuccessUrl("/")
.and().exceptionHandling().accessDeniedPage("/")
//.authenticationEntryPoint(ajaxEntryPoint);
;
}
}
Response header
pragma: no-cache
date: Sun, 05 Nov 2017 11:08:12 GMT
x-content-type-options: nosniff
x-frame-options: DENY
content-type: application/json;charset=UTF-8
cache-control: no-cache, no-store, max-age=0, must-revalidate
transfer-encoding: chunked
x-xss-protection: 1; mode=block
expires: 0
js console image

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource asp.net

I am facing problem with Cross Domain Ajax call. When I call a asp.net WebMethod through Ajax Call I got warning : Reason: CORS preflight channel did not succeed
Here is complete code
Server Code :
using System;
using Customers.BLL;
using Newtonsoft.Json;
using System.Web.Script.Serialization;
using System.Web.Services;
using System.Web.Http.Cors;
[EnableCors(origins: "*", headers: "*", methods: "*")]
public partial class API_Default : System.Web.UI.Page
{
static string ApplicationPath = "";
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static string ValidateUser(string UserName)
{
string strJson = "";
var User = Members.GetCustMaster(UserName);
if (User != null)
{
User.BankName = ApplicationPath + (User.BankName.ToString() != "" ? "Images/Photos/" + User.BankName : "images/avatar.png");
strJson = JsonConvert.SerializeObject(User);
}
else
{
JavaScriptSerializer json = new JavaScriptSerializer();
Failure failure = new Failure();
strJson = json.Serialize(failure);
}
return strJson;
}
}
[Serializable]
public class Failure
{
public bool Status { get { return false; } }
public string Result { get { return "Record Not found"; } }
}
I have added Headers in Web.config
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Credentials" value="true" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, X-Token" />
<add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
</customHeaders>
</httpProtocol>
Thisis how I am trying to call this webmethod
<head>
<title></title>
<script src="jquery-1.11.1.min.js"></script>
<script >function GetJSon() {
var obj = {};
obj.UserName = $("#txt").val();
$.ajax({
type: "POST",
url: "http://someurl.net/webservices/default.aspx/ValidateUser",
contentType: "application/json; charset=utf-8",
dataType: "json",
crossDomain: true,
data: JSON.stringify(obj),
success: function (msg) {
console.log();
alert(msg.d)
$("#test").html(msg.d)
},
error: function () {
console.log();
}
});
}</script>
</head>
<body>
<input type="text" value="demo" id="txt" />
<input type="button" onclick="GetJSon()" value="jSon" />
Response : <div id="test">
</div>
</body>
</html>
Response for preflight has invalid HTTP status code 404

CakePHP ajax CSRF token mismatch

I am making an ajax request with Csrf component load in my AppController
However I get the error {"message":"CSRF token mismatch.","url":"\/module_slides\/loadDeck.json","code":403}
Here is the request header
POST /module_slides/loadDeck.json HTTP/1.1
Host: www.hotelieracademy.com
Connection: keep-alive
Content-Length: 18
Origin: https://www.hotelieracademy.com
X-XSRF-TOKEN: 3d3901b1de9c5182dce2877c9e1d9db36cdf46a6
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
Referer: https://www.hotelieracademy.com/courses_employees/player/70
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: csrfToken=3d3901b1de9c5182dce2877c9e1d9db36cdf46a6; CAKEPHP=3n6lpi94hrdgsg8mv4fsnp1m30; _ga=GA1.2.2010364689.1424741587
My ajax code
$.ajax({
url: '/module_slides/loadDeck.json',
type: 'POST',
headers: { 'X-XSRF-TOKEN' : this.csrfToken },
beforeSend: function (xhr) {
xhr.setRequestHeader('X-CSRF-Token', this.csrfToken);
},
dataType: 'json',
data: {
I have left the beforeSend: as suggest by another post but does not seem to alter the header so I added headers:
I use a hidden input to get the CsfR token to use in my js code
<input id="csrfToken" type="hidden" value="<?= $this->request->getParam('_csrfToken') ?>">
I've met the same problem.
Probably, this is the answer to add "_csrfToken":"xxxxxxx" to data{}.
$.ajax({
url: '/module_slides/loadDeck.json',
type: 'POST',
headers: { 'X-XSRF-TOKEN' : this.csrfToken },
beforeSend: function (xhr) {
xhr.setRequestHeader('X-CSRF-Token', this.csrfToken);
},
dataType: 'json',
data: {
"_csrfToken":"3d3901b1de9c5182dce2877c9e1d9db36cdf46a6"
}
This is my blog.but it's Japanese Only.
http://www.tsuji75.com/?p=62
Here is my solution.
For the CSRF token, I am creating an empty cakephp form and it provides the CSRF token.
Also, I do not unlock any action. instead I do unlock fields.
Ref: https://book.cakephp.org/3.0/en/controllers/components/security.html
here is my working example.
Scenario: Ajax call to add an event was failing due to cakephp 3 CSRF token mismatch issue.
Solution:
I have created an empty form in the view so it can provide CSRF token for my form and then attached the required input fields before the ajax. In the form itself, I unlocked the hidden fields. This way I do not disturb CSRF component.
In VIEW
<?= $this->Form->create(false, [
'id' => "ajaxForm",
'url' => ['controller' => 'XYZ', 'action' => 'add'],
'class'=> "addUpdateDeleteEventForm"
] );
$eventdata = [];
?>
<?= $this->Form->unlockField('id'); ?>
<?= $this->Form->unlockField('start'); ?>
<?= $this->Form->unlockField('end'); ?>
<?= $this->Form->unlockField('title'); ?>
<?= $this->Form->button('Submit Form', ['type' => 'submit']);?>
<?= $this->Form->end(); ?>
Ajax:
var id = $("<input>")
.attr("type", "hidden")
.attr("name", "id").val(id);
var titleField = $("<input>")
.attr("type", "hidden")
.attr("name", "title").val(title);
var startTime = $("<input>")
.attr("type", "hidden")
.attr("name", "start").val(start);
var endTime = $("<input>")
.attr("type", "hidden")
.attr("name", "end").val(end);
$('#ajaxForm').append(id);
$('#ajaxForm').append(titleField);
$('#ajaxForm').append(startTime);
$('#ajaxForm').append(endTime);
var ajaxdata = $("#ajaxForm").serializeArray();
$.ajax({
url:$("#ajaxForm").attr("action"),
type:"POST",
data:ajaxdata,
dataType: "json",
success:function(response)
{
toastr.success(response.message, response.title);
calendar.fullCalendar("removeEvents");
calendar.fullCalendar("refetchEvents");
},
error: function(response)
{
toastr.error(response.message, response.title);
}
});
Hope this helps.

Resources