I am working on a user registration feature with frontend React and backend Laravel 8. When the input fields are valid it is working fine. But even if any of the input fields fail in the backend validation it throws an error saying "access has been blocked by CORS policy". Here is an image of the error. My question is why is everything working fine when the input fields are valid, but throwing an unrelatable error when it fails. And below is my code:
Frontend (React)
const register = async(values) => {
const {email, serial, password, confirm_password} = values;
const details = {email : email, serial : serial, password: password, password_confirmation : confirm_password};
try {
const result = await fetch('http://192.168.1.15:8000/api/v1/register', {
method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(details),
})
const data = await result.json();
if (data.error) {
console.log(data.error)
}
else {
setUser(data.data)
cookies.set('Noortap', data.data, { path: '/' });
console.log(cookies.get('Noortap'))
}
}
catch (err) {
console.log(err)
}
}
Backend (Laravel)
public function register(Request $request)
{
$request->validate([
'name' => 'max:255',
'email' => 'required|unique:users,email|email|max:255',
'serial' => ['required','max:255', new IsValidSerialNumber],
'password' => 'required|confirmed',
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'is_admin' => 0,
'password' => Hash::make($request->password)
]);
\App\Models\Tag::where('serial_number', $request->serial)->update([
'assigned' => 1,
'user_id' => $user->id
]);
// // response
// return $this->login($request);
return $request;
}
That is because your frontend and backend are on separate "domains". In this case, they are on the same domain but a different port. You will need to add http://192.168.1.15:3000 to the $except array in app/Http/Middleware/VerifyCsrfToken.php so that you dont face a CORS policy issue.
So your file should look something like this:
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array<int, string>
*/
protected $except = [
'192.168.1.15:3000'
];
}
Related
This is the API code to send the request. It works fine when I send it with only one parameter.
const handlecreate=(evt)=>{
evt.preventDefault();
const fd = new FormData();
fd.append('image', picture);
axios.post('http://127.0.0.1:8000/api/post/store',{fd,form});
)
}
In laravel as backend:
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'image' => 'required',
'category'=>'required',
'slug'=>'required',
'heading'=>'required',
]);
if ($validator->fails())
{
return response(['errors'=>$validator->errors()->all()], 200);
}
}
If we want to post the data with multiple parameter that is store in different state hooks then we have to append the each data of hooks
const handlecreate=(evt)=>{
const fd = new FormData();
fd.append('image', picture);
fd.append('heading',form.heading);
axios.post('http://127.0.0.1:8000/api/post/store',fd);
}
I would be answering the question in bit depth, so that it can help other as well with thorough understanding.
Note: Make sure you removed the cross origin issues if you are using react as front end or any other framework
Backend work
First you need to make the route properly in your laravel api located in laravel: routes/api
Let's assume we created the route in the api file and connected our controller likewise:
Route::post('/storeData', 'StoreController#store');
Now we need a controller on the same name in:
App/http/controllers/StoreController
In the StoreController we need the function which is connected that is store function in the StoreController:
public function store(Request $request)
{
$this->validate($request, [
'vin' => 'required|unique:autos,vin',
'lot' => 'required|unique:autos,lot',
]);
$autos = new Auto; //this is the model(mvc)
$autos->vin = $request->vin;
$autos->lot = $request->lot;
$autos->save();
return response()->json([
'success_message' => 'success auto is created',
], 200); // a message to the front end after successful execution of the query
}
Frontend Work
export const storeData = () => {
let axiosConfig = {
headers: {
"Content-Type": "application/json;charset=UTF-8",
Accept: "application/json",
Authorization: `Bearer ${decryptedToken}`, // if you had made the passport 0Auth2
}
};
const autoData = new FormData();
autoData.append("vin", autoData.vin);
autoData.append("lot", autoData.lot);
axios
.post(`http://127.0.0.1:8000/api/autoDataStore`, autoData, axiosConfig)
.then((response) => {
if (response.data.success_message) {
console.log(response.data);
} else if(response.data.error_message){
}
})
.catch((err) => {
console.log(err.response.data.errors)
});
};
I have React frontend and Laravel Backend Application which authenticates user using JWT. The login process is working properly and I can get the authenticated user with the me function of JWT. But now when I try to access contents based on the authenticated user, I get 401 error. I'm adding my react axios function and also my laravel controller that has the function which is giving the error. Please point out what am I doing wrong on it. Any help is very much appreciated. Thank you.
React axios function:
export const fetchMyApplications = () => {
return async dispatch => {
const url = `/auth/my-applications`;
var formdata = new FormData();
const token = getCookie("userToken");
const response = await api
.get(
url,
{
headers: {
Authorization: `Bearer ${token}`
}
}
)
.then(res => {
return res;
})
.catch(error => {
return error.response;
});
dispatch({
type: "FETCH_MY_APLICATIONS",
payload: response
});
};
}
Laravel controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use App\Models\Application;
class ApplyController extends Controller
{
public function __construct()
{
\Config::set('auth.providers.users.model', \App\Applicant::class);
$this->middleware('auth:api', ['except' =['personalDetails']]);
}
public function myApplications(){
try {
$user = auth()->userOrFail();
$applications = Application::where('applicant_id', $user->applicant_id)->with('course')->get();
return response()->json(['applications'=> $applications], 200);
}catch (\Tymon\JWTAuth\Exceptions\UserNotDefinedException $e) {
return response()->json(['status'=> false, 'errors'=> 'Unauthenticated User'], 401);
}
}
}
Auth Config:
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
'hash' => false,
],
],
Postman Checking Logged In User:
Postman Trying to get applications of logged in user:
I figured out what was wrong. Actually it was not with my code, rather it was apache configuration on linode server. I added authorization header to the apache config file and it worked.
im trying to redirect after storing some data passed using axios(ReactJS).
the controller is working fine it store data in the DB ,but it wont redirect to the destination i want.
my component code that s work perfectly:
async onSubmitButton(e) {
e.preventDefault();
const formData = new FormData();
formData.append("objet", this.state.objet);
formData.append("id_p", this.state.id_p);
const response = await axios.post("/CreateCDM", formData, {
headers: {
"Content-Type": "multipart/form-data"
}
})
.catch(err => {
console.log(err);
this.setState({errorMessage: err.message});
})
}
and this is my controller :
public function store(Request $request)
{
$dm = new DossierMedical;
$id = Auth::user()->id;
$dm->objet = $request->objet;
$dm->analyseRequis = 0;
$dm->medcine = $id;
$dm->patient = $request->id_p;
$dm->save(); //Working , i cant see that in the DB
$specialite = DB::table('specialites')
->where('nom', 'not like', 'Radiologie')
->where('nom', 'not like', 'Laboratoir d\'Analyse')
->SELECT('*')
->GET();
return view('dossierMedicale.patient.dm' ,
['objet' => $request->objet ,
'id' => $dm->id ,
'Specialite' => $specialite
]);
}
the problem is that im not redirecting to the view i want ,and i cant see any server error in the console.
PS : if i post the data using blade.php(without Reactjs) it redirect me
The redirection should be done in ReactJS instead of Laravel's controller.
Sample in ReactJS:
onSubmitButton(e) {
e.preventDefault();
const formData = new FormData();
formData.append("objet", this.state.objet);
formData.append("id_p", this.state.id_p);
axios.post("/CreateCDM", formData, {
headers: {
"Content-Type": "multipart/form-data"
}
})
.then(response => {
// obtain the data return from controller
const { objet, id, Specialite } = response.data;
//perform your redirection to other routes.
window.location.href = "/other-routes/";
})
.catch(err => {
console.log(err);
this.setState({errorMessage: err.message});
})
}
Sample in Controller:
public function store(Request $request)
{
$dm = new DossierMedical;
$id = Auth::user()->id;
$dm->objet = $request->objet;
$dm->analyseRequis = 0;
$dm->medcine = $id;
$dm->patient = $request->id_p;
$dm->save(); //Working , i cant see that in the DB
$specialite = DB::table('specialites')
->where('nom', 'not like', 'Radiologie')
->where('nom', 'not like', 'Laboratoir d\'Analyse')
->SELECT('*')
->GET();
return response()->json([
'objet' => $request->objet ,
'id' => $dm->id ,
'Specialite' => $specialite
], 200);
}
Premise · What you want to realize
I want to get json from API server using React's axios.
Front end: React.js
Back end: Laravel5.5
The authentication method uses Laravel default AUTH.
Since we want to return JSON only when logging in on the API side, we use middleware (auth) with Laravel routing.
Problems occurring · Error messages
If you hit api from the browser, it will be displayed normally, but if you go through React's axios you get the following error. 401 (Unauthorized)
It can be taken by accessing from the browser
Source Codes
■React.js
import axios from 'axios';
const host = window.location.protocol + '//api.' + window.location.hostname ;
const path = window.location.pathname
export const getIndex = nowId =>
axios
.get(host + '/v1/movie/' + nowId, {
headers: {
'Accept': 'application/json',
},
})
.then((results) => {
const status = results.status
if(typeof result === 'undefind'){
return status
}
const indexDatas = results.data[0]
return indexDatas
}).catch(
error => {}
);
■Laravel (API)
・/routes/web.php
Route::get('/auth/login/{token}', 'Auth\LoginController#auth');
Route::get('/auth/logout', 'Auth\LoginController#logout');
Route::get('/v1/sidemenu', 'ChallengersController#sidemenu');
Route::group(['prefix'=>'v1', 'middleware' => ['auth']],function(){
// Movie
// =======
Route::group(['prefix'=>'movie', 'middleware' => ['cors']],function(){
Route::get('/contents', 'MovieController#contents');
Route::get('/addContents', 'MovieController#addContents');
Route::get('/{id}/getChapter', 'MovieController#getChapter');
Route::get('/{id}/getReview', 'MovieController#getReview');
Route::get('/{id}/reviewCount', 'MovieController#getReviewCount');
Route::post('/postReview', 'MovieController#postReview');
Route::get('/review/commit', 'MovieController#reviewCommit');
Route::get('/{id}', 'MovieController#detail');
Route::get('/list', 'MovieController#index');
});
// Podcast
// =======
Route::group(['prefix'=>'audio'],function(){
Route::get('/list', 'PodcastController#index');
Route::get('/{id}', 'PodcastController#detail');
});
// Lecture
Route::group(['prefix'=>'lecture'],function(){
Route::get('/', 'LecturesController#index');
Route::get('/{id}', 'LecturesController#show');
Route::get('/{id}/schedules', 'LectureSchedulesController#index');
});
});
・/config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
Is the solution to this problem to give authentication information to the header of the request side (React's axios)?
Then, what kind of things should be put in the header?
I tried putting the same thing as the figure below, but it did not move.
API Header
axios
.get(host + '/v1/movie/' + nowId, {
headers: {
'Accept': 'application/json',
'Set-Cookie': 'laravel_session=eyJpdiI6IitBVldGM0VORzFZRk1ick1IY2Z5d1E9PSIsInZhbHVlIjoiT3JPeUVHc3BSaE5vRXF0KzB3N2xXRkdXb0xwMDVvS0RZR1VQM0xmMFkySnNrS01KRHVXMTFWNVhTU1wvMTVwa3RDRmNvajVMZGhiU2t4dFEzY1FxdkFnPT0iLCJtYWMiOiJjMjJhYWQ3ZjczMDgwOTExZDI5Njc5OTY4YTg5ZjgxMGI1MDlmYmNkZDJkZTFmNDA5YWMyZjRjOTYxYzc0YzNlIn0%3D;'
},
})
.then((results) => {
const status = results.status
if(typeof result === 'undefind'){
return status
}
const indexDatas = results.data[0]
return indexDatas
}).catch(
error => {}
);
your are able to open in browser, because you have added the routes in web.php.
in order to open from api , you have to add routes in api.php.
I am getting above error while fetching some data from the API. Following is the code of the action creator where I am trying GET the data:
import { FETCH_USER } from './types';
import axios from 'axios';
export const fetchUser = () => async dispatch => {
console.log('fetchUser');
const res= await axios.get('/api/current_user');
dispatch({ type: FETCH_USER, payload: res });
};
Also when I am debugging in the code editor, console is giving me below error:
SyntaxError: Unexpected token import
Generally this error comes when the url/location provided inside GET method is not correct.
So check the url/location again and correct it.
So most probably there is some mistake here : '/api/current_user'
In my case it was a minor syntax error (a misplacement of my brackets).
My code looked like this:
axiosget("/api-url").then(
(response) => {
doSomething();
}), () => {
doError();
}
);
instead of this:
axiosget("/api-url").then(
(response) => {
doSomething();
}, () => {
doError();
});
);
If you get this error message it means that your error handling-code isn't there or that it could not be reached, therefore the promise was unhandled (since the catch-part of your wasn't properly setup).
If you get this message always doublecheck your syntax!
If your are using laravel for API and vue/Nuxtjs for frontend and axios for send data to API....
This type of errors can be faced for laravel validation error sending not in correct way using try{} catch(){} block or receiving errors by axios not in correct way to using try() catch(){} block.
Here, try catch block using for error handling.
If your API routes called the public function its name "register()", so your function inside your controller have to like following...(I am using laravel-8 for API)
public function register(Request $request) {
try {
$fields = $request->validate([
'name' => 'required|string',
'email' => 'required|string|email|unique:users',
'password' => 'required|string|confirmed',
]);
$user = User::create([
'name' => $fields['name'],
'email' => $fields['email'],
'password' => bcrypt($fields['password'])
]);
$token = $user->createToken('myapptoken')->plainTextToken;
$response = [
'user' => $user,
'token' => $token,
];
return response()->json($response, 200);
} catch(ValidationException $e) {
return response()->json([
'status' => 'error',
'msg' => 'error',
'errors' => $e->errors()
], 422);
}
}
and Frontend Nuxt or vue methods name is "registerNewUser()" so, codes can be following for error handling...
async registerNewUser() {
try {
let data = {
name : this.name.trim(),
email : this.email.trim(),
password : this.password.trim(),
password_confirmation : this.password_confirmation.trim(),
};
let headers = {
headers: {
'Accept': 'application/json',
}
};
await this.$axios
.post("/api/register", data, headers)
.then((response) => {
console.log("response", response);
if(response) {
// console.log(response)
} else {
}
});
} catch(err) {
// here we are receiving validation errors
console.log("Err == ", err.response);
console.log(err.response.data.errors);
}
}
You are receiving response inside axios then block or receive error inside catch block using err.response
Here,
let data = {
name : this.name.trim(),
email : this.email.trim(),
password : this.password.trim(),
password_confirmation : this.password_confirmation.trim(),
};
Given codes is for data of Nuxtjs or vuejs. If not know that you can using like following data or any other data...
let data = {
name : 'Kallol',
email : 'kallolray94#gmail.com',
password : '123456',
password_confirmation : '123456',
};