I am making an app in ionic and the backend is made in Laravel. I am working on a password reset functionality, and I keep getting the above mentioned error, when I am testing endpoints in chrome. This is the code for the contact information function:
sendContactConfirmation: function(contact, reset) {
var defer = $q.defer();
if(reset == 'reset'){
var endpointUrl = $http.post(AppSettings.apiUrl + "/users/reset", { phone: contact });
}
else {
var endpointUrl = $http.post(AppSettings.apiUrl + "/users", { phone: contact });
}
endpointUrl.then(function(result) {
service.set(result.data.user);
defer.resolve(result);
}, function(error) {
defer.reject(error);
});
return defer.promise;
},
And these are the routes in my Laravel back-end:
Route::group(['jwt.auth', ['except' => ['authenticate']], 'prefix' => 'api', 'namespace' => 'Api'], function() {
Route::post('authenticate', 'AuthenticateController#authenticate');
Route::get('authenticate/user', 'AuthenticateController#getAuthenticatedUser');
Route::post('users', 'UsersController#register');
Route::post('users/reset', 'UsersController#resetContact');
Route::put('users/{user}/reset', 'UsersController#resetPassword');
Route::put('users/{user}', 'UsersController#update');
Route::put('users/{user}/activate', 'UsersController#activate');
Route::post('users/{user}/pic', 'UsersController#uploadPicture');
});
And this is the resetContact function:
public function resetContact(Request $request)
{
$this->validate(
$request,
['phone' => 'required|regex:/^[0-9]{8}$/']
);
$user = User::where('phone', $request->get('phone'))->firstOrFail();
if ($user) {
try {
$this->sendValidationCode($user, 'reset');
}
catch (\Exception $e) {
throw new ApiException($e->getMessage(), 500);
}
}
return response()->json([
'user' => $user,
]);
}
Not sure why do I get this 400 Bad request error for this.
When using Laravel JWT make sure you always send the token for all routes under jwt.auth otherwise you will get the error 400 = Token not provided. In ionic make sure your toke is provided on each call to your laravel endpoint to avoid this error.
Related
I've been hitting wall for a while now with this, simply I can't get it where is the problem. So I've got backend Laravel and front Vue; logging in is alright, I get token but when I get into one of the routes with auth:api I get "message":"Unauthenticated.". I save token on the front, so should I send it with any request to backend or there is other way around it?
LoginController.php
public function login(Request $request)
{
$login = $request->validate([
'email' => 'required',
'password' => 'required',
]);
if(Auth::attempt($login))
{
return response(['message' => 'Invalid login']);
}
$user = User::where('email', $request->email)->first();
$accessToken = $user->createToken('Laravel Password Grant Client')->accessToken;
return response()->json(['user' => $user, 'access_token' => $accessToken]);
}
api.php
Route::namespace('\\')->middleware('auth:api')->group(function(){
Route::resource('budget', BudgetController::class);
});
user.js
const state = {
token: localStorage.getItem('access_token') || null,
isAuthenticated: localStorage.getItem('access_token') !== null
}
const getters = {
isAuthenticated: state => state.isAuthenticated
}
const actions = {
async retrieveToken({commit}, payload){
console.log(payload)
const response = axios.post(url + '/login', payload)
.then(response => {
const token = response.data.access_token
localStorage.setItem('access_token', token)
commit('setToken', token)
})
}
}
const mutations = {
setToken: (token) => state.token = token
}
Alright, so simply in my second module I used token as a header like this:
const state = {
budget: [],
header: {
headers: {
Authorization: `Bearer ${localStorage.getItem("access_token") || null}`,
withCredentials: true,
"Access-Control-Allow-Origin": "*"
},
}
};
const getters = {
allBudget: (state) => state.budget,
};
const actions = {
async fetchBudget({ commit, state }) {
const response = await axios.get(url, state.header);
console.log(state.header);
commit("setBudget", response.data);
},
};
After that I was getting CORS error so i needed to add two directives at the end of the file xampp\apache\conf\httpd.conf
Header Set Access-Control-Allow-Origin *
Header Set Access-Control-Allow-Headers *
I have a login form in vue.js. I just have to login user with vue.js and laravel. Once login user will redirect to a dashboard which is already developed with laravel only. I am trying to login but it is not working and auth()->guard returns null so that user redirected to the login page instead of the dashboard. When I use postman in that case it works well.
Vue js
this.$http.post('http://localhost/project/admin/vendors/validate_login',{phone_number : this.phone_number},{
headers: {
"Access-Control-Allow-Origin": "*"
}
})
.then((response) =>{
if(response.data.status == 'success')
{
window.location = "http://localhost/project/admin/vendors/dashboard";
}
})
Laravel - validate login :
public function validate_login(Request $request)
{
$arr_rules = array();
$status = false;
$remember_me = "";
$arr_rules['phone_number'] = "required";
$validator = validator::make($request->all(),$arr_rules);
if($validator->fails())
{
return response()->json([
'status' => 'error',
'msg' => "Mobile number is empty"
]);
}
$obj_group_vendor = $this->UsersModel
->where('phone_number',$request->only('phone_number'))
->first();
if($obj_group_vendor)
{
if($this->auth->attempt(['phone_number' => $request->phone_number,
'role_id' => 3]))
{
return response()->json([
'status' => 'success',
'msg' => "You are successfully login to your account."
]);
}
else
{
return response()->json([
'status' => 'error',
'msg' => "Invalid login credential."
]);
}
}
else
{
return response()->json([
'status' => 'error',
'msg' => "Invalid login credentials."
]);
}
return;
}
Route:
$web_vendor_path = config('app.project.vendor_panel_slug');
Route::group(array('prefix' => $web_vendor_path,
'middleware'=> ['vendor_auth_check']), function ()
{
$route_slug = 'vendor_';
Route::post('validate_login', ['as' => $route_slug.'validate',
'uses' => $module_controller.'validate_login']);
});
Route::group(array('prefix' => $web_vendor_path,
'middleware'=>'auth_vendor'), function ()
use($web_vendor_path)
{
$route_slug = 'vendor_';
$module_controller = "Vendor\DashboardController#";
Route::get('/dashboard',['as' => $route_slug.'index',
'uses' => $module_controller.'index']);
});
Any help would be appreciated.
Just spitting out some ideas here:
Try to set the 'Content-Type': 'application/x-www-form-urlencoded' header for all POST requests.
In addition, the Access-Control-Allow-Origin is a header that should be in the response of the webserver. It is not a header you should be sending in your request from javascript.
Make sure you have web middleware enabled on your route file in app/Providers/RouteServiceProvider.php
Then check in app/Http/Kernel.php that \Illuminate\Session\Middleware\StartSession::class, is added and enabled in $middlewareGroups['web']
When doing a POST/PATCH/PUT/DELETE request from the browser, you need to include the CSRF token of your page.
this.$http.post('http://localhost/project/admin/vendors/validate_login',{phone_number : this.phone_number},{
headers: {
"Access-Control-Allow-Origin": "*",
"X-CSRF-TOKEN": document.head.querySelector('meta[name="csrf-token"]').content
}
})
.then((response) =>{
if(response.data.status == 'success')
{
window.location = "http://localhost/project/admin/vendors/dashboard";
}
})
And be sure that you have the CSRF included as a meta tag in all your pages:
<meta name="csrf-token" content="{{ csrf_token() }}">
If you're using an api guard, do this auth()->guard('api').
I have a problem following this tutorial to implement a simple chat in Laravel using Pusher and Vue.js: Link tutorial.
My app.js file in assets/js where I make the request is this one:
const app = new Vue({
el: '#app',
data: {
tweets: []
},
created() {
this.showTweets();
Echo.private('chat')
.listen('TweetSentEvent', (e) => {
this.tweets.push({
tweet: e.tweet.tweet,
user: e.user
});
});
},
methods: {
showTweets() {
axios.get('/tweets').then(response => {
this.tweets = response.data;
});
},
addTweet(tweet) {
this.tweets.push(tweet);
axios.post('tweets', tweet).then(response => {
console.log(response.data);
});
}
}
});
My web.php routes:
Auth::routes();
Route::get('/', 'TweetController#index');
Route::get('tweets', 'TweetController#showTweets')-
>middleware('auth');
Route::post('tweets', 'TweetController#sentTweet
My controller is this one:
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
return view('chat');
}
public function showTweets(){
return Tweet::with('user')->get();
}
public function sendTweet(Request $request){
$user = Auth::user();
$tweet = $user->tweets()->create([
'tweet' => $request->input('tweet')
]);
broadcast(new TweetSentEvent($user, $tweet))->toOthers();
//return ['status' => 'Tweet Sent!'];
}
When I'm running the app and I try to send a tweet through a POST request clicking on my send button, this error apperas on the console:
POST http://localhost/youChat/public/tweets 500 (Internal Server Error)
Uncaught (in promise) Error: Request failed with status code 500
at createError (app.js:13931)
at settle (app.js:35401)
at XMLHttpRequest.handleLoad (app.js:13805)
Everything seems to be fine... Any help? Thanks in advance!!
Good I am trying to delete through ajax but I get the following error:
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
I searched the error and apparently appears by the token so I have done what they recommended, I added in the view this:
<meta name="csrf-token" content="{{ csrf_token() }}">
ajax:
$('#delete').on('click', function(){
var x = $(this);
var delete_url = x.attr('data-href')+'/'+x.attr('data-id');
$.ajax({
url: delete_url,
type:'DELETE',
headers:{
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr('content')
},
success:function(result){
alert('success');
},
error:function(result){
alert('error');
}
});
});
controller:
public function destroy($id)
{
$appointment = Appointment::find($id);
if(appointment == null) {
return Response()->json([
'message'=>'error delete.'
]);
}
$appointment->delete();
return Response()->json([
'message'=>'sucess delete.'
]);
}
route:
Route::name('appointments.destroy')->delete('/citas/{id}', 'AppointmentController#destroy');
it is certainly a token error because if I do not need it on the route it does it perfectly ...
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'citas/*'
];
}
You can check the exact error on developers console, network tab. Look there for your request and check the preview or open it in a new chrome's tab.
Posted code has a typo, maybe it is in your file too? You missed to add $ to your appointment variable.
public function destroy($id)
{
$appointment = Appointment::find($id);
if($appointment == null) {
return Response()->json([
'message'=>'error delete.'
]);
}
$appointment->delete();
return Response()->json([
'message'=>'sucess delete.'
]);
}
Trying to integrate APIs built in Laravel 5.4 with ionic 2 and struggling handle the error
What I want to do:
Authenticate the login using Laravel Password service ( OAuth2 ).
Once authenticated, it would return the access token.
Access Token is passed in the header in a GET API call to receive the
user details.
I am able to #1 and #2 but got stuck at #3.
Here is my code of login.ts
public login() {
this.showLoading();
this.auth.login(this.loginCredentials).subscribe(allowed => {
if (allowed) {
setTimeout(() => {
this.loading.dismiss();
this.nav.setRoot(HelloIonicPage)
});
} else {
this.showError("Access Denied");
}
},
error => {
this.showError(error);
});
}
auth is a service provider, that has login method.
//Function to get access token
public login(credentials) {
if (credentials.email === null || credentials.password === null) {
return Observable.throw("Please insert credentials");
} else {
return Observable.create(observer => {
var link = 'http://localhost/XXX/public/oauth/token';
var vars = {
password: "XXX",
username: "XXXXXX",
grant_type: 'password',
client_id: "XXXXX",
client_secret: 'XXXXXX',
scope: ''
}
this.http.post(link, vars)
.map(res => res.json())
.subscribe(
data => { let user = this.getUserFromAccessToken(data);
console.log(user);
observer.next(user);
},
err => { observer.error(err.json()); }
() => {
console.log('Completed..');
}
);
});
}
}
//Function to get user from the accessToken
private getUserFromAccessToken(oAuthData) {
let headers = new Headers({ 'Content-Type': 'application/json','Accept': 'application/json','Authorization': 'Bearer ' + oAuthData.access_token });
let options = new RequestOptions({ headers: headers });
let link = 'http://localhost/XXXX/public/api/v1/user';
return this.http.get(link, options)
.map(res => res.json())
.subscribe(
data => this.currentUser = data.user,
err => this.error = err
);
}
currentUser and error are defined as properties of the AuthService class.
How should I ensure that an error is thrown either in case the access token is not returned or user is not returned from the access token.