Laravel + Angular 2 http POST error - php

Im currently building a login system using angular 2 framework (ionic). This login have 2 post data which are:
Email
Password
I've built the API and ran using postman. Everything is fine. It's returning desired response. But the angular 2 POST doesnt seems to do what it should do. For example this is my request code:
var data = JSON.stringify({email: email, password: password});
this.http.post('https://dev.domain.com/api/login', data)
.subscribe(
res => {
console.log(res);
loading.dismiss();
},
err => {
console.log("Error occured");
loading.dismiss();
}
);
Laravel returns 200 response and desired data but Angular 2 is always identifying the response as error. This is my Laravel codes:
public function login(Request $request) {
$data = $request->json()->all();
$email = $data['email'];
$password = $data['password'];
if (Auth::attempt(['email' => $email, 'password' => $password])) {
$user = User::where('email', $email)->first();
return response()->json(['data' => $user])->header('Content-Type', 'application/json');
} else {
$returnData = array(
'status' => 'error',
'message' => 'An error occurred!'
);
return response()->json($returnData, 500)->header('Content-Type', 'application/json');
}
}
I tried installing CORS plugin. Still seems to not solve this issue.
Can anyone help me on this? Thanks

Change your HTTP status code From 500 to 200 or leave empty.
return response()->json($returnData, 200)->header('Content-Type', 'application/json');
OR
return response()->json($returnData)->header('Content-Type', 'application/json');

Related

Laravel eloquent in Lumen api dont save when data comes from HTTP Client Laravel, but when i test with Postman that works

I have a page with send data to an Lumen API. I send the data using the Laravel Http Client, like this:
$url = env('API_ADDRESS');
$data= [
'p1' => $request->input('p1'),
'p2' => $request->input('p2')
];
$headers = [
'key' => env('API_KEY')
];
$req = Http::withHeaders($headers)->post($url, $data);
The status code from this request is 200.
In my API, i have a code like to receive the data and save it:
public function SaveReq(Request $request)
{
$data = [
'status'=> 'success',
'msg'=> ''
];
try {
$req = new Requisition();
$req->p1 = $request->input('p1');
$req->p2 = $request->input('p2');
$req->save();
} catch (ErrorException $e) {
$data['status'] = 'error';
$data['msg'] = $e->getMessage();
} finally {
return json_encode($data);
}
}
In my application that send the request, i can see the json of the api returns, but the api dont save the data, but if i send a request with this same data using Postman, my api save the data.
What am i doing wrong in the application that sends the data?
check http method in your application and postman be same
before save data , use dd($request->all()); to sure data
send correctly

ionic v3 angular v5 cant pass CSRF to php Slim server

I have made PHP Slim server. Authentication for it and CSRF.
I want to use it as a REST Server.
I have a created an App using IonicFramework which uses Angular.
I want to authenticate myself with this code
let hheaders:Headers=new Headers();
hheaders.append('Access-Control-Allow-Origin' , '*');
hheaders.append('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
hheaders.append('Accept','application/json');
let options = new RequestOptions({ headers:hheaders});
let data = new FormData();
data.append("email", this.myForm.email);
data.append("password", this.myForm.password);
data.append("csrf_name", this.myForm.csrf_name);
data.append("csrf_value", this.myForm.csrf_value);
return this.http.post('http://10.1.3.101:8088/public/auth/signinservice',data,this.options)
.map(res => res.json())
.toPromise();
But I always get Failed CSRF check! I do not know what is the problem. At this point the Slim Server is basic. It is very simple and similar to this Github project with new methods in AuthController.php
like
public function getSignInService($request, $response){
$nameKey = $this->csrf->getTokenNameKey();
$valueKey = $this->csrf->getTokenValueKey();
$name = $request->getAttribute($nameKey);
$value = $request->getAttribute($valueKey);
$tokenArray = [
$nameKey => $name,
$valueKey => $value
];
return $response->write(json_encode($tokenArray));
}
and
public function postSignInService($request, $response, $args){
$auth = $this->auth->attempt(
$request->getParam('email'),
$request->getParam('password')
);
if(!$auth){
$data = array('status' => 'error');
$newResponse = $response->withJson($data, 203);
return $newResponse;
}
$data = array('status' => 'Successful login');
$newResponse = $response->withJson($data, 200);
return $newResponse;
}
and added routes for the methods.
How could i successfully authenticate with Ionic v3 and Angular v5?

Plivo - 404 error, call not found, when I try to record inbound call

I am trying to record the inbound call but so far I am only getting the 404 call not found error when record is activated.
This is my code so far (I am using Laravel and latest Plivo SDK):
public function __construct(Request $request)
{
$this->authId = config('AUTH_ID');
$this->authToken = config('AUTH_TOKEN');
$this->sourceNumber = config('sms.SMS_SOURCE_NUMBER');
$this->_answerURL = config('voiceCall.CALL_ANSWER_URL');
$this->_recordURL = config('voiceCall.INBOUND_RECORD_URL');
$this->_hangupURL = config('voiceCall.HANGUP_URL');
$this->_plivo = new RestClient($this->authId, $this->authToken);
$this->_response = new Response();
$this->_mp3Url = 'https://s3.amazonaws.com/plivocloud/Trumpet.mp3';
$this->_request = $request;
}
The answer method:
public function answer()
{
$response = $this->_response;
$response->addPlay($this->_mp3Url);
$response->addRecord([
'action' => $this->_recordURL,
'startOnDialAnswer' => "true",
'redirect' => "false",
'maxLength' => 600
]);
Log::useDailyFiles(storage_path().'/logs/debug.log');
Log::info([
'Record' => 'This is from inbound answer',
'Response' => $response
]);
return response($response->toXML(), 200)
->header('Content-Type', 'text/xml');
}
The record method:
public function record()
{
Log::useDailyFiles(storage_path().'/logs/debug.log');
$uuid = $this->_request->input('CallUUID');
Log::info(['This is Call UUID' => $uuid]);
$response = $this->_plivo->calls->startRecording($uuid);
Log::info([
'Record' => 'This is from record inbound record',
'Response' => $response,
'CallUUID' => $this->_request->input('CallUUID'),
'Request' => $this->_request->all(),
]);
}
The request is giving back the proper call uuid, and
$response = $this->_plivo->calls->startRecording($uuid);
is the code which is used in the docs. Does anyone have an idea what am I doing wrong here?
Plivo Sales Engineer here.
Is this an incoming call to your Plivo number? I see that you're returning an XML that contains a Play and Record element. This Record XML will take care of recording the call after the Play ends.
Are you making a Record API request to record this again? Which Call UUID are you passing to this API request?
For an inbound call, the Call UUID is sent to the answer URL. Are you using this Call UUID?

Sending more data with Laravel passport oauth/token

So, I'm using Laravel+Passport and so far is working fine.
But, I would like to made a small change to the passport code(well, not in the vendor folder, I hope), once that I would request the User to change it's password in case that he is doing the first login.
So, what I would need is two things (I believe):
1 - How can I add one more info to the oauth/token response? Together with the access_token, I would like to add one column from the DB that is needsNewPassword=true/false.
2 - In case that needsNewPassword is true, then, the app will redirect to another screen, where the user will set a new password. I would set the new password, remove the flag for needsNewPassword and send back a new access_token to the user. The user then, would use only that access_token. How can I regenerate a new access_token?
Thanks for you help! João
Right,
I answering my own question, in case someone needs to do the same. Maybe is not the best way, but is working.What I did is:
Create a new route, like /api/login that points to a method (be sure that is Outside of your middleware "auth", once that it's not sending the token in thi call). E.g: Route::post('/login', 'Auth\LoginController#apiLogin');
in the method, you do a request to the oauth/token and, with the result, you add the fields that you want.
test
function apiLogin(Request $request) {
$tokenRequest = $request->create('/oauth/token', 'POST', $request->all());
$request->request->add([
"client_id" => 'your_client_id',
"client_secret" => 'your_client_secret',
"grant_type" => 'password',
"code" => '*',
]);
$response = Route::dispatch($tokenRequest);
$json = (array) json_decode($response->getContent());
$json['new_value'] = '123456';
$response->setContent(json_encode($json));
return $response
}
This is working for me. In my case, I also have just one app so, my client_id, client_secret, grant_type and code is added in the server side. The client only need to pass username(or email, depends of what you are using) and password and then it will get the access_token and the other info that I want to send as well.
Hope that this helps someone else too.
Cheers,
joao
#joao.sauer
Your own answer is working like a charm, but if you wan't a bit more freedom, you could extend Passport's own AccessTokenController.
A simple example:
use App\Models\User;
use Exception;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use League\OAuth2\Server\Exception\OAuthServerException;
use Psr\Http\Message\ServerRequestInterface;
use Response;
class AccessTokenController extends \Laravel\Passport\Http\Controllers\AccessTokenController
{
public function issueToken(ServerRequestInterface $request)
{
try {
//get username (default is :email)
$username = $request->getParsedBody()['username'];
//get user
$user = User::where('email', '=', $username)->firstOrFail();
//issuetoken
$tokenResponse = parent::issueToken($request);
//convert response to json string
$content = $tokenResponse->getBody()->__toString();
//convert json to array
$data = json_decode($content, true);
if(isset($data["error"]))
throw new OAuthServerException('The user credentials were incorrect.', 6, 'invalid_credentials', 401);
//add access token to user
$user = collect($user);
$user->put('access_token', $data['access_token']);
return Response::json(array($user));
}
catch (ModelNotFoundException $e) { // email notfound
//return error message
}
catch (OAuthServerException $e) { //password not correct..token not granted
//return error message
}
catch (Exception $e) {
////return error message
}
}
}
credits to Messi89:
Laravel Passport - Customize The Token Response
I found a simple solution without need new request, controller or extends, just add parameters to request and call issueToken via app, it can useful for starter:
// in routes/api.php
Route::post('/token',function(Request $request){
$request->request->add([
'grant_type' => 'password',
'client_id' => '2',
'client_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
]);
return app()->call('\Laravel\Passport\Http\Controllers\AccessTokenController#issueToken');
});
Also can add try...catch block to handle exceptions or add parameters to response before send to client
Route::post('/token',function(Request $request){
$request->request->add([
'grant_type' => 'password',
'client_id' => '2',
'client_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
]);
try {
$response = app()->call('\Laravel\Passport\Http\Controllers\AccessTokenController#issueToken');
$newResponse = json_decode($response->content());
// Add parameters to response here
$newResponse->user = ['user'=>'user','pass'=>'pass'];
return Response()->json($newResponse);
}catch (Laravel\Passport\Exceptions\OAuthServerException $e) {
if ($e->statusCode() == 400) {
return response()->json(['message' => 'Invalid request. Please enter username and password.'], $e->statusCode());
} else if ($e->statusCode() == 401) {
return response()->json(['message' => 'Your credentials are incorrect. Please try again.'], $e->statusCode());
}
return response()->json('Something went wrong on the server. Please try later.', $e->statusCode());
}
});

Slim PHP Not returning the correct Status Code

I'm creating my first api, and I chose to use Slim PHP, so far, I think it's a great lightweight framework to do the basics of what I need. The only issue I've really had was my route responses not returning the correct status codes. I want to return 200 on a successful login, and a 403 on a failed login with incorrect credentials. All I get back is a 200 no matter what it returns. The logic is working, because I can see the correct JSON being returned, just the status code doesn't get changed.
Index.php
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require 'vendor/autoload.php';
$app = new \Slim\App;
$app->options('/{routes:.+}', function ($request, $response, $args) {
return $response;
});
$app->add(function ($req, $res, $next) {
$response = $next($req, $res);
return $response
->withHeader('Access-Control-Allow-Origin', 'http://mysite')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
});
require_once 'api/login.php';
$app->run();
Login.php
$app->post('/api/login', function ($request, $response){
require_once 'db.php';
$q = "SELECT * FROM blog_admin WHERE username = ? AND password = ?";
$stmt = $mysqli->prepare($q);
$stmt->bind_param('ss', $user, $pass);
$user = $request->getParsedBody()['username'];
$pass = md5($request->getParsedBody()['password']);
if($stmt->execute()){
$stmt->store_result();
if($stmt->num_rows > 0){
$token = md5(uniqid($user, true));
date_default_timezone_set("America/Toronto");
$logged_in = date('Y/m/d');
$data = array(
"flash" => 'success',
"message" => '<strong>SUCCESS:</strong> You have entered the correct login information! Please wait while you are redirected...',
'_token' => $token,
'logged_in' => $logged_in
);
$q = "UPDATE blog_admin SET _token=?, last_logged_in=?";
$stmt = $mysqli->prepare($q);
$stmt->bind_param('ss', $token, $logged_in);
if($stmt->execute()){
$response->withJson($data, 200);
}else{
$data = array(
"flash" => 'danger',
"message" => '<strong>ERROR:</strong> Could not login! Please try again later!'
);
$response->withJson($data, 403);
}
}else{
$data = array(
"flash" => 'danger',
"message" => '<strong>ERROR:</strong> The Username/Password you have entered is incorrect. Please try again.'
);
$response->withJson($data, 403);
}
}else{
$data = array(
"flash" => 'danger',
"message" => '<strong>ERROR:</strong> Could Not Run the SQL'
);
$response->withJson($data, 500);
}
return $response;
});
I'm not sure what the issue might be, so any ideas will be much appreciated.
The PSR-7 Response which slim3 uses is a immutable value object, so it cannot be changed.
F.ex.
$response->withJson($data, 200);
Will not change $response it returns the changed Response so you either have to return this
return $response->withJson($data, 200);
or you need to reassign the variable with the new value, and then return it at the end of the route function.
$response = $response->withJson($data, 200);
// other code
return $response;

Categories