CORS issue when adding form data to backend - vuejs2

Beginner in using vue and express here. I've been trying to follow a certain tutorial where they add a simple form data to a database but for some reason it gives this error on mine:
Access to XMLHttpRequest at 'http://localhost:3000/create' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Here is what I made in the backend:
app.use('/create',(req,res,next)=>{
res.set({
"Access-Control-Allow-Origin":"http://localhost:8080",
"Access-Control-Allow-Headers":"Content-Type",
})
var mysql = require('mysql')
var connection = mysql.createConnection(config)
// SET ?
// `FirstName`=?, `LastName`=?, `Email`=?, `ContactNumber`=?
// [req.body.FirstName,req.body.LastName,req.body.Email,req.body.ContactNumber]
var sql = "INSERT INTO `guest` SET `FirstName`=?, `LastName`=?, `Email`=?, `ContactNumber`=?"
connection.query(sql,[req.body.FirstName,req.body.LastName,req.body.Email,req.body.ContactNumber],(err,results,fields)=>{
connection.end()
if(err){
next(err)
}else{
res.json([true,results]) //.insertId
}
})
})
and on the front-end:
<b-form v-model="contactForm" #submit="check();addGuest();" #reset="onReset" v-if="show">
<b-form-group
id="input-group-1"
label="Email address:"
label-for="input-1"
description="Give us an email to give a receipt to"
>
<b-form-input
id="input-1"
v-model="contactForm.Email"
type="email"
required
placeholder="Enter email"
></b-form-input>
</b-form-group>
<b-form-group id="input-group-2" label="Your Name:" label-for="input-2">
<b-form-input
id="input-2"
v-model="contactForm.FirstName"
required
placeholder="Enter first name"
></b-form-input>
<b-form-input
id="input-3"
v-model='contactForm.LastName'
required
placeholder="Enter last name"
></b-form-input>
</b-form-group>
<b-form-group
id="input-group-3"
label="Contact Number"
label-for="input-3"
description="Give us a contact number to give a receipt to"
>
<b-form-input
id="input-4"
v-model='contactForm.ContactNumber'
type="tel"
required
placeholder="Enter Contact Number"
></b-form-input>
</b-form-group>
<b-button type="submit" variant="primary">Submit</b-button>
<b-button type="reset" variant="danger">Reset</b-button>
</b-form>
Method script:
addGuest(){
//POST a guest
// evt.preventDefault()
// console.log(this.contactForm)
axios.post('http://localhost:3000/create',this.contactForm)
.then((res)=>{
console.log(res.data)
})
.catch((err)=>{
alert('AJAX error')
})
}
Am I missing something big here? I literally just modified what I've seen on the tutorial.

It's not that simple to "activate" Access-Control-Allow-Origin in Express - but it's not hard either:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "YOUR-DOMAIN.TLD"); // update to match the domain you will make the request from
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.get('/', function(req, res, next) {
// Handle the get for this route
});
app.post('/', function(req, res, next) {
// Handle the post for this route
});
Source: https://enable-cors.org/server_expressjs.html
You have to set res.header and pass it to Express to use that setting.

Related

Verify if reCaptcha v3 in Nuxt is working properly

I'm installing #nuxtjs/recaptcha on my nuxt project, which is google reCaptcha V3. It looks like it's working great it's always returning success result from the servers like below.
{success: true, challenge_ts: '2022-05-05T11:37:06Z', hostname: 'localhost', score: 0.9}
But I'm not sure this work properly because the challenge does not appear. Recaptcha as I know it, should have a challenge that must be met. But why doesn't the challenge appear here?
Maybe it needs to be triggered with some event handler? But in the documentation example I didn't saw any things related about it or maybe I just do not realize it.
May be im missing something important, so I need your help to figure it out.
My template code
<template>
<div class="container">
<h1 align="center">SEND EMAIL TO US!</h1>
<div class="layout">
<form #submit.prevent="onSubmit">
<div class="basic-info">
<div class="name">
<label for="">Name :</label>
<b-form-input v-model="data.name" placeholder="Name"></b-form-input>
<div v-if="validation.name" class="mt-2">
<b-alert show variant="danger">{{ validation.name[0] }}</b-alert>
</div>
</div>
<div class="email">
<label for="">Email :</label>
<b-form-input
v-model="data.email"
placeholder="Email"
></b-form-input>
<div v-if="validation.email" class="mt-2">
<b-alert show variant="danger">{{ validation.email[0] }}</b-alert>
</div>
</div>
<div class="messege">
<label for="">Messege :</label>
<b-form-textarea
id="textarea"
v-model="data.messege"
placeholder="Enter Messege..."
rows="8"
max-rows="8"
></b-form-textarea>
<div v-if="validation.messege" class="mt-2">
<b-alert show variant="danger">
{{ validation.messege[0] }}
</b-alert>
</div>
</div>
<hr />
<b-button type="submit" variant="outline-primary">
SEND EMAIL
</b-button>
<hr />
<b-alert v-model="alert" show :variant="variant">
{{ result_messege }}
</b-alert>
</div>
</form>
</div>
</div>
</template>
my script code
<script>
export default {
async mounted() {
try {
await this.$recaptcha.init()
} catch (e) {
console.log(e)
}
},
methods: {
async onSubmit() {
try {
this.loading = true
// Start the verification process
const response = await this.verifyCaptcha()
console.log(response)
// Display error message if verification was not successful
if (!response.success) {
this.$recaptcha.reset()
this.loading = false
this.errorStatus = true
this.notificationMessage =
'There was an error with your reCaptcha verification. Please try again.'
return
}
// If verification was successful, send the message
await this.sendMail()
this.errorStatus = false
this.notificationMessage =
'Thank you for reaching out. We will get back to you as soon as possible'
this.loading = false
this.$recaptcha.reset()
} catch (error) {
this.loading = false
console.log(error)
}
},
async verifyCaptcha() {
try {
const token = await this.$recaptcha.execute()
console.log(token)
const response = await this.$axios.$post(
`/captcha-api/siteverify?secret=${process.env.SECRET_KEY}&response=${token}`
)
return response
} catch (error) {
this.loading = false
return error
}
},
},
}
</script>
This is totally normal, this is the whole concept of the v3 as you can see in this video: https://youtu.be/tbvxFW4UJdU
More details are also here: https://developers.google.com/recaptcha/docs/v3
And here: https://www.google.com/recaptcha/about/
So far, the feature is exactly this: do not require any interaction from the user but rather use some mouse trackers/AI to know if it's potentially malicious or not.

How to properly configure my backend in order to receive data from my form? I'm using Vue.js

My goal is to send emails with nodemailer, so I need to do that from my backend. I have a form in my vue component and I'm trying to send the data to http://localhost:3000/ but I get an error : POST http://localhost:3000/ 404 (Not Found). I'm using Axios to do that.
When I make a get request I get a response without any errors, but I cannot make a post request.
First, I created a server just to deploy my site on heroku (responsive proposes), but now I'm not sure if my backend configuration is ok to receive data from my client side. I looked around but I didn't find a specific answer to my problem.
Contact.vue:
<form class="form" #submit.prevent="sendData">
<ul>
<li>
<label for="name">Name</label>
<input type="text" id="name" name="user_name" v-model="name">
</li>
<li>
<label for="mail">E-mail</label>
<input type="email" id="mail" name="user_email" v-model="email">
</li>
<li>
<label for="msg">Message:</label>
<textarea id="msg" name="user_message" v-model="message"></textarea>
</li>
</ul>
<button type="submit" class="btn">Send</button>
</form>
<script>
import * as axios from 'axios';
export default {
data(){
return{
name: "",
email: "",
message: ""
}
},
methods: {
sendData(){
console.log(this.name, this.email,this.message);
axios.post("http://localhost:3000/",{
name: this.name,
email: this.email,
message: this.message
})
.then(response => {
console.log(response)
})
.catch(error =>{
this.error = error;
})
}
}
}
</script>
My server.js:
const express = require('express');
const port = process.env.PORT || 3000;
var cors = require('cors')
const app = express();
app.use(cors())
app.use(express.static(__dirname + "/dist/"));
app.get("/", function(req, res) {
res.sendfile(__dirname + '/dist/index.html');
})
app.listen(port);
console.log('Server started...');
You are sending a POST request to http://localhost:3000/, but this is set as a GET in your server. So try:
app.post("/", function(req, res) {
res.sendfile(__dirname + '/dist/index.html');
})

Insert and updating the data to database from frontend

I am new to web development. I am working in development of an angular application. I have developed an Angular form in front end, Node.js and Sql server in backend. I need some help to connect my angular form to the sql server database. I want to save the data from my angular form to my sql server database.
Versions:
Angular CLI: 8.0.3
Node: 10.16.0
OS: win32 x64
Angular: 8.0.1
I have tried using the restful api to insert data through the server page using post and get.
How can i to connect my angular form to sql databse and insert and update the data when the submit button in my angular form is clicked.
var express = require("express");
var bodyParser = require("body-parser");
var tediousExpress = require("express4-tedious");
var path = require("path")
var app = express();
// Body Parser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//CORS Middleware
app.use(function (req, res, next) {
//Enabling CORS
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, contentType,Content-Type, Accept, Authorization");
next();
});
app.get('/', function (req, res) {
var sql = require("mssql");
// config for your database
var config = {
server:'******',
database: '*******',
user:'******',
password: '*****',
};
// connect to your database
sql.connect(config, function (err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.query('select * from dbo.contact', function (err, recordset) {
if (err)
console.log(err)
else
// send records as a response
res.send(recordset);
});
});
});
app.use("/contact", (req, res) => {
res.sendfile( __dirname + "/src/app/contact/contact.component.html");
});
app.use("/product", (req, res) => {
res.sendfile( __dirname + "/src/app/product/product.component.html");
});
app.use("/homepage", (req, res) => {
res.sendfile( __dirname + "/src/app/home/home.component.html");
});
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Listening on port ${port}....`));
<div style="text-align:center">
<h1 class="well">
We are available here for you
</h1>
<div class="loader" *ngIf="dataloading"></div>
<div class = "row">
<div class="column">
<div class ="container">
<div class="col-md-5">
<div class="form-area">
<form role="form" (ngSubmit)="processForm()">
<br style="clear:both">
<h3 style="margin-bottom: 50px; text-align: center;">Contact</h3>
<div class="form-group">
<input required ngModel name="Name" #FirstName="ngModel" (change)="log(Name)" type="text" class="form-control" id="Name" name="name" placeholder="Name" [(ngModel)]="name" required>
<div class="alert alert-danger" *ngIf="Name.touched && !Name.valid" > Name is required.</div>
</div>
<div class="form-group">
<input required type="email" class="form-control" id="email" name="email" placeholder="Email" [(ngModel)]="email" required>
<div class="alert alert-danger" *ngIf="email.touched && !email.valid" > Email is required.</div>
</div>
<div class="form-group">
<input type="phone" class="form-control" id="mobile" name="mobile" placeholder="Mobile Number" [(ngModel)]="mobile" required>
</div>
<div class="form-group">
<input type="text" class="form-control" id="subject" name="subject" placeholder="Subject" [(ngModel)]="subject" required>
</div>
<div class="form-group">
<textarea class="form-control" type="textarea" id="message" name="message" placeholder="Message max(200)" [(ngModel)]="message" maxlength="140" rows="7"></textarea>
</div>
<hr class="mb-4">
<button type="button" id="submit" name="submit" class="btn btn-primary btn-lg btn-block" (click)="save(name, email, mobile, subject, message)">Submit</button>
</form>
</div>
</div>
</div>
````
````contact.component.ts
import { Component, OnInit} from '#angular/core';
import {HttpClient} from '#angular/common/http';
import {HttpErrorResponse} from '#angular/common/http';
import {Router} from '#angular/router';
#Component({
selector: 'app-contact',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.css']
})
export class ContactComponent {
title = 'Simple Example Contact-us page using Angular 4';
public data:any=[]
constructor(private http: HttpClient){
}
save(name, email, mobile, subject, message): void {
this.data['name']= name;
this.data['email']= email;
this.data['mobile']= mobile;
this.data['subject']= subject;
this.data['message']= message;
console.log(this.data);
//add request to send email or into mysql
this.http.post<any>('/contact1', this.data).subscribe(
res => {
console.log(res);
},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
console.log("Client-side error occured.");
} else {
console.log("Server-side error occurred.");
}
});
}
}
````

keeping a user logged in from a Vue.js SPA outside the SPA (websanova)

I have a SPA built in Vue.js - using JWT for authentication and an API layer provided by Laravel.
I now require a single page to run (outside the SPA/Vue) directly from Laravel, but only after the user has logged in. Once there i need to access Auth::user() - but it seems that Laravel doesn't now the user is actually logged in.
Not entirely sure what code to put here, but here goes anyway:
Login.vue
<template>
<div>
<div class="alert alert-danger" v-if="error">
<p class="help-block" v-if="errors">{{ errors }}</p>
<p class="help-block" v-else >There was an error, unable to sign in with those credentials.</p>
</div>
<form autocomplete="off" #submit.prevent="login" method="post">
<div class="form-group">
<label for="email">E-mail</label>
<input type="email" id="email" class="form-control" placeholder="user#example.com" v-model="email" required>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" class="form-control" v-model="password" required>
</div>
<button type="submit" class="btn btn-default">Sign in</button>
</form>
</div>
</template>
<script>
export default {
data(){
return {
email: null,
password: null,
error: false,
errors: {}
}
},
methods: {
login(){
var app = this
this.$auth.login({
params: {
email: app.email,
password: app.password
},
success: function (resp) {
//app.error = true;
//console.log('>>> '+resp.response.data.msg);
//app.errors = resp.response.data.msg;
},
error: function (resp) {
app.error = true;
//console.log('>>> '+resp.response.data.msg);
app.errors = resp.response.data.msg;
},
rememberMe: true,
redirect: '/dashboard',
fetchUser: true,
});
},
}
}
</script>
routes/api.php
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::post('auth/register', 'AuthController#register');
Route::post('auth/login', 'AuthController#login');
Route::post('findmember', 'FoundItemController#searchMember');
Route::post('sendmessage', 'MessagingController#sendMessage');
Route::group(['middleware' => 'jwt.auth'], function(){
//
// User auth controllers/methods should go here
//
Route::get('packages', 'PackageController#getPackages');
Route::get('auth/user', 'AuthController#user');
Route::post('auth/logout', 'AuthController#logout');
Route::get('user/items', 'ItemController#getItems');
Route::post('user/items/add', 'ItemController#addItem');
Route::get('user/mobile_numbers', 'MobileNumbersController#getNumbers');
Route::post('user/mobile_numbers/add', 'MobileNumbersController#addNumber');
Route::post('user/mobile_numbers/primary', 'MobileNumbersController#setPrimary');
Route::post('user/mobile_numbers/delete', 'MobileNumbersController#removeNumber');
Route::post('subscription/paypal/complete');
});
Route::group(['middleware' => 'jwt.refresh'], function(){
Route::get('auth/refresh', 'AuthController#refresh');
});
/routes/web.php
Route::get('/', function () {
return view('welcome');
});
Auth::routes(['verify' => true]);
Route::get('/verify', 'AuthController#verify')->name('verify');
Route::group(['middleware' => 'jwt.auth'], function(){
Route::get('testing', 'HomeController#index');
});
I tried adding the middleware wrapper around my home controller (see
below), but this returns null), I feel i need to tell Laravel
that the user is logged in somehow, but am completely stumped.
../controllers/HomeController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use Illuminate\Support\Facades\Auth;
use JWTAuth;
use Log;
class HomeController extends Controller
{
public function index()
{
//return view('home');
dd(Auth::user());
}
}
I don't know laravel at all, but here is the general idea of what I would do, from your single page:
on a first request, query a route on laravel to get the jwt (sometime this route is /me).
on the next requests, inject the jwt in the page headers. The token name is token and the value is something like Bearer ${token}.
On the server side, check if the token is valid before to proceed the request.
Hope this helps.
you can use this method, I used in my project it work cool.
auth('api')->user();

angular 2 service does not send data - Unprocessable Entity

i am trying to send data(email,password) on http://localhost:8000/api/signin with form
but it keeps returning me this response
Unprocessable Entity
{"email":["The email field is required."],"password":["The password field is required."]}
service
login(email:string,password:string){
console.log(email,password);
return this._http.post('http://localhost:8000/api/signin',JSON.stringify({email:email,password:password}))
.map(res =>{
// login successful if there's a jwt token in the response
let user = res.json();
if(user && user.token){
localStorage.setItem('currentUser',JSON.stringify(user));
}
});
}
Login.Component.ts
login(){
console.log(this.model.email,this.model.password);
this.authenticationservice.login(this.model.email,this.model.password)
.subscribe(
data => {
this.router.navigate([this.returnUrl]);
});
form
<div class="col-md-6 col-md-offset-3">
<h2>Login</h2>
<form name="form" (ngSubmit)="login()">
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" name="email" [(ngModel)]="model.email" required />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" name="password" [(ngModel)]="model.password" required />
</div>
<div class="form-group">
<button class="btn btn-primary">Login</button>
</div>
<div *ngIf="error" class="alert alert-danger">{{error}}</div>
</form>
response in postman
http://image.prntscr.com/image/b6c5a8d985834283aa0501c8cb4caed9.png
Try this:
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let options = {
headers: headers
};
let body = JSON.stringify({email:email,password:password});
return this.http.post(url, body, options).map(...);
Add Content-Type : application/json header to your request :
login(email:string,password:string) {
let bodyString = JSON.stringify({ email: email, password: password });
let headers = new Headers({ 'Content-Type': 'application/json' });
return this._http.post('http://localhost:8000/api/signin', bodyString, {headers: headers})
.map(res =>{
// login successful if there's a jwt token in the response
let user = res.json();
if(user && user.token){
localStorage.setItem('currentUser',JSON.stringify(user));
}
});
}